Merge XML and VFP support to this branch.
diff --git a/ChangeLog.csl b/ChangeLog.csl
index 0aa7530..0d1484b 100644
--- a/ChangeLog.csl
+++ b/ChangeLog.csl
@@ -1,3 +1,51 @@
+2006-04-02  Daniel Jacobowitz  <dan@codesourcery.com>
+
+	* Makefile.def (host_modules, dependencies): Add expat.
+	* configure.in (host_libs): Add expat.
+	* Makefile.in, configure: Regenerate.
+	* expat: New directory.
+
+	* gdb/Makefile.in: Add expat, new files, and xml-builtin.c.  Update
+	dependencies.
+	* gdb/acinclude.m4: Include stdint.m4.
+	* gdb/configure.ac: Use AC_C_BIGENDIAN and GCC_HEADER_STDINT.
+	* gdb/aclocal.m4, gdb/config.in, gdb/configure: Regenerate.
+
+	* gdb/auxv.h: Remove target_auxv_read prototype.
+	* gdb/auxv.c, gdb/avr-tdep.c, gdb/ia64-tdep.c, gdb/linux-nat.c,
+	gdb/procfs.c: Use target_read_whole.
+	* gdb/sparc-tdep.c: Use target_read.
+
+	* gdb/frame.c: Work around null frame_id handling.
+
+	* gdb/breakpoint.c, gdb/f-valprint.c, gdb/infcmd.c, gdb/inflow.c,
+	gdb/infrun.c, gdb/stack.c, gdb/valops.c, gdb/varobj.c,
+	gdb/cli-cmds.c, gdb/testsuite/gdb.base/default.exp,
+	gdb/tui/tui-disasm.c, gdb/tui/tui-source.c,
+	gdb/tui/tui-winsource.c: Selected frame fixups.
+
+	* gdb/README.AVAIL, gdb/available.c, gdb/available.h,
+	gdb/parse-avail.c, gdb/sha1.c, gdb/features/feature_to_c.sh,
+	gdb/features/gdb-target.dtd: New files.
+	* gdb/arm-tdep.c: Handle missing FPA, present VFP, and
+	self-described registers.  Decode VFP register numbers from DWARF.
+	* gdb/arm-tdep.h: Add flags for VFP and FPA.
+	* gdb/gdbarch.sh: Add available_features_support and feature_set.
+	Export the arch's obstack.  Check feature sets.  Improve error
+	handling.
+	* gdb/gdbarch.c, gdb/gdbarch.h: Regenerated.
+	* gdb/infcmd.c: Trigger architecture selection.
+	* gdb/remote.c: Available feature support.  qPacketInfo support.
+	Improved g/G packet support.  Improved qPart support.
+	qPart:features support.
+	* gdb/symfile.c: Adjust download_write_size.
+	* gdb/target.c: Revise partial transfer support.  Handle available
+	features method.  Add target_read_whole.
+	* gdb/target.h: Add the available features object and methods.
+	* gdb/doc/gdb.texinfo: Document new features.
+
+	* gdb/symfile.h: Include symtab.h.
+
 2006-03-31  Nathan Sidwell  <nathan@codesourcery.com>
 
 	* gdb/config/m68k/monitor.mt (TDEPFILES): Remove unneeded
diff --git a/Makefile.def b/Makefile.def
index 3227a44..3c87dce 100644
--- a/Makefile.def
+++ b/Makefile.def
@@ -47,6 +47,7 @@
 host_modules= { module= diff; };
 host_modules= { module= dosutils; no_check= true; };
 host_modules= { module= etc; };
+host_modules= { module= expat; };
 host_modules= { module= fastjar; no_check_cross= true; };
 host_modules= { module= fileutils; };
 host_modules= { module= findutils; };
@@ -297,6 +298,7 @@
 dependencies = { module=all-gdb; on=all-build-bison; };
 dependencies = { module=all-gdb; on=all-build-byacc; };
 dependencies = { module=all-gdb; on=all-sim; };
+dependencies = { module=all-gdb; on=all-expat; };
 
 dependencies = { module=configure-libgui; on=configure-tcl; };
 dependencies = { module=configure-libgui; on=configure-tk; };
diff --git a/Makefile.in b/Makefile.in
index 37d5510..15a98ab 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -566,6 +566,7 @@
     maybe-configure-diff \
     maybe-configure-dosutils \
     maybe-configure-etc \
+    maybe-configure-expat \
     maybe-configure-fastjar \
     maybe-configure-fileutils \
     maybe-configure-findutils \
@@ -694,6 +695,7 @@
 all-host: maybe-all-diff
 all-host: maybe-all-dosutils
 all-host: maybe-all-etc
+all-host: maybe-all-expat
 all-host: maybe-all-fastjar
 all-host: maybe-all-fileutils
 all-host: maybe-all-findutils
@@ -819,6 +821,7 @@
 info-host: maybe-info-diff
 info-host: maybe-info-dosutils
 info-host: maybe-info-etc
+info-host: maybe-info-expat
 info-host: maybe-info-fastjar
 info-host: maybe-info-fileutils
 info-host: maybe-info-findutils
@@ -923,6 +926,7 @@
 dvi-host: maybe-dvi-diff
 dvi-host: maybe-dvi-dosutils
 dvi-host: maybe-dvi-etc
+dvi-host: maybe-dvi-expat
 dvi-host: maybe-dvi-fastjar
 dvi-host: maybe-dvi-fileutils
 dvi-host: maybe-dvi-findutils
@@ -1027,6 +1031,7 @@
 html-host: maybe-html-diff
 html-host: maybe-html-dosutils
 html-host: maybe-html-etc
+html-host: maybe-html-expat
 html-host: maybe-html-fastjar
 html-host: maybe-html-fileutils
 html-host: maybe-html-findutils
@@ -1131,6 +1136,7 @@
 TAGS-host: maybe-TAGS-diff
 TAGS-host: maybe-TAGS-dosutils
 TAGS-host: maybe-TAGS-etc
+TAGS-host: maybe-TAGS-expat
 TAGS-host: maybe-TAGS-fastjar
 TAGS-host: maybe-TAGS-fileutils
 TAGS-host: maybe-TAGS-findutils
@@ -1235,6 +1241,7 @@
 install-info-host: maybe-install-info-diff
 install-info-host: maybe-install-info-dosutils
 install-info-host: maybe-install-info-etc
+install-info-host: maybe-install-info-expat
 install-info-host: maybe-install-info-fastjar
 install-info-host: maybe-install-info-fileutils
 install-info-host: maybe-install-info-findutils
@@ -1339,6 +1346,7 @@
 installcheck-host: maybe-installcheck-diff
 installcheck-host: maybe-installcheck-dosutils
 installcheck-host: maybe-installcheck-etc
+installcheck-host: maybe-installcheck-expat
 installcheck-host: maybe-installcheck-fastjar
 installcheck-host: maybe-installcheck-fileutils
 installcheck-host: maybe-installcheck-findutils
@@ -1443,6 +1451,7 @@
 mostlyclean-host: maybe-mostlyclean-diff
 mostlyclean-host: maybe-mostlyclean-dosutils
 mostlyclean-host: maybe-mostlyclean-etc
+mostlyclean-host: maybe-mostlyclean-expat
 mostlyclean-host: maybe-mostlyclean-fastjar
 mostlyclean-host: maybe-mostlyclean-fileutils
 mostlyclean-host: maybe-mostlyclean-findutils
@@ -1547,6 +1556,7 @@
 clean-host: maybe-clean-diff
 clean-host: maybe-clean-dosutils
 clean-host: maybe-clean-etc
+clean-host: maybe-clean-expat
 clean-host: maybe-clean-fastjar
 clean-host: maybe-clean-fileutils
 clean-host: maybe-clean-findutils
@@ -1651,6 +1661,7 @@
 distclean-host: maybe-distclean-diff
 distclean-host: maybe-distclean-dosutils
 distclean-host: maybe-distclean-etc
+distclean-host: maybe-distclean-expat
 distclean-host: maybe-distclean-fastjar
 distclean-host: maybe-distclean-fileutils
 distclean-host: maybe-distclean-findutils
@@ -1755,6 +1766,7 @@
 maintainer-clean-host: maybe-maintainer-clean-diff
 maintainer-clean-host: maybe-maintainer-clean-dosutils
 maintainer-clean-host: maybe-maintainer-clean-etc
+maintainer-clean-host: maybe-maintainer-clean-expat
 maintainer-clean-host: maybe-maintainer-clean-fastjar
 maintainer-clean-host: maybe-maintainer-clean-fileutils
 maintainer-clean-host: maybe-maintainer-clean-findutils
@@ -1912,6 +1924,7 @@
     maybe-check-diff \
     maybe-check-dosutils \
     maybe-check-etc \
+    maybe-check-expat \
     maybe-check-fastjar \
     maybe-check-fileutils \
     maybe-check-findutils \
@@ -2043,6 +2056,7 @@
     maybe-install-diff \
     maybe-install-dosutils \
     maybe-install-etc \
+    maybe-install-expat \
     maybe-install-fastjar \
     maybe-install-fileutils \
     maybe-install-findutils \
@@ -2113,6 +2127,7 @@
     maybe-install-diff \
     maybe-install-dosutils \
     maybe-install-etc \
+    maybe-install-expat \
     maybe-install-fastjar \
     maybe-install-fileutils \
     maybe-install-findutils \
@@ -8356,6 +8371,343 @@
 
 
 
+.PHONY: configure-expat maybe-configure-expat
+maybe-configure-expat:
+@if expat
+maybe-configure-expat: configure-expat
+configure-expat: 
+	@: $(MAKE); $(unstage)
+	@r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	test ! -f $(HOST_SUBDIR)/expat/Makefile || exit 0; \
+	$(SHELL) $(srcdir)/mkinstalldirs $(HOST_SUBDIR)/expat ; \
+	$(HOST_EXPORTS) \
+	echo Configuring in $(HOST_SUBDIR)/expat; \
+	cd "$(HOST_SUBDIR)/expat" || exit 1; \
+	case $(srcdir) in \
+	  /* | [A-Za-z]:[\\/]*) topdir=$(srcdir) ;; \
+	  *) topdir=`echo $(HOST_SUBDIR)/expat/ | \
+		sed -e 's,\./,,g' -e 's,[^/]*/,../,g' `$(srcdir) ;; \
+	esac; \
+	srcdiroption="--srcdir=$${topdir}/expat"; \
+	libsrcdir="$$s/expat"; \
+	$(SHELL) $${libsrcdir}/configure \
+	  $(HOST_CONFIGARGS) $${srcdiroption}  \
+	  || exit 1
+@endif expat
+
+
+
+
+
+.PHONY: all-expat maybe-all-expat
+maybe-all-expat:
+@if expat
+TARGET-expat=all
+maybe-all-expat: all-expat
+all-expat: configure-expat
+	@: $(MAKE); $(unstage)
+	@r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(HOST_EXPORTS) \
+	(cd $(HOST_SUBDIR)/expat && \
+	  $(MAKE) $(FLAGS_TO_PASS)  $(TARGET-expat))
+@endif expat
+
+
+
+
+.PHONY: check-expat maybe-check-expat
+maybe-check-expat:
+@if expat
+maybe-check-expat: check-expat
+
+check-expat:
+	@: $(MAKE); $(unstage)
+	@r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(HOST_EXPORTS) \
+	(cd $(HOST_SUBDIR)/expat && \
+	  $(MAKE) $(FLAGS_TO_PASS)  check)
+
+@endif expat
+
+.PHONY: install-expat maybe-install-expat
+maybe-install-expat:
+@if expat
+maybe-install-expat: install-expat
+
+install-expat: installdirs
+	@: $(MAKE); $(unstage)
+	@r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(HOST_EXPORTS) \
+	(cd $(HOST_SUBDIR)/expat && \
+	  $(MAKE) $(FLAGS_TO_PASS)  install)
+
+@endif expat
+
+# Other targets (info, dvi, etc.)
+
+.PHONY: maybe-info-expat info-expat
+maybe-info-expat:
+@if expat
+maybe-info-expat: info-expat
+
+info-expat: \
+    configure-expat 
+	@: $(MAKE); $(unstage)
+	@[ -f ./expat/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(HOST_EXPORTS) \
+	for flag in $(EXTRA_HOST_FLAGS) ; do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	echo "Doing info in expat" ; \
+	(cd $(HOST_SUBDIR)/expat && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" \
+	          info) \
+	  || exit 1
+
+@endif expat
+
+.PHONY: maybe-dvi-expat dvi-expat
+maybe-dvi-expat:
+@if expat
+maybe-dvi-expat: dvi-expat
+
+dvi-expat: \
+    configure-expat 
+	@: $(MAKE); $(unstage)
+	@[ -f ./expat/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(HOST_EXPORTS) \
+	for flag in $(EXTRA_HOST_FLAGS) ; do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	echo "Doing dvi in expat" ; \
+	(cd $(HOST_SUBDIR)/expat && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" \
+	          dvi) \
+	  || exit 1
+
+@endif expat
+
+.PHONY: maybe-html-expat html-expat
+maybe-html-expat:
+@if expat
+maybe-html-expat: html-expat
+
+html-expat: \
+    configure-expat 
+	@: $(MAKE); $(unstage)
+	@[ -f ./expat/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(HOST_EXPORTS) \
+	for flag in $(EXTRA_HOST_FLAGS) ; do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	echo "Doing html in expat" ; \
+	(cd $(HOST_SUBDIR)/expat && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" \
+	          html) \
+	  || exit 1
+
+@endif expat
+
+.PHONY: maybe-TAGS-expat TAGS-expat
+maybe-TAGS-expat:
+@if expat
+maybe-TAGS-expat: TAGS-expat
+
+TAGS-expat: \
+    configure-expat 
+	@: $(MAKE); $(unstage)
+	@[ -f ./expat/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(HOST_EXPORTS) \
+	for flag in $(EXTRA_HOST_FLAGS) ; do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	echo "Doing TAGS in expat" ; \
+	(cd $(HOST_SUBDIR)/expat && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" \
+	          TAGS) \
+	  || exit 1
+
+@endif expat
+
+.PHONY: maybe-install-info-expat install-info-expat
+maybe-install-info-expat:
+@if expat
+maybe-install-info-expat: install-info-expat
+
+install-info-expat: \
+    configure-expat \
+    info-expat 
+	@: $(MAKE); $(unstage)
+	@[ -f ./expat/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(HOST_EXPORTS) \
+	for flag in $(EXTRA_HOST_FLAGS) ; do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	echo "Doing install-info in expat" ; \
+	(cd $(HOST_SUBDIR)/expat && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" \
+	          install-info) \
+	  || exit 1
+
+@endif expat
+
+.PHONY: maybe-installcheck-expat installcheck-expat
+maybe-installcheck-expat:
+@if expat
+maybe-installcheck-expat: installcheck-expat
+
+installcheck-expat: \
+    configure-expat 
+	@: $(MAKE); $(unstage)
+	@[ -f ./expat/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(HOST_EXPORTS) \
+	for flag in $(EXTRA_HOST_FLAGS) ; do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	echo "Doing installcheck in expat" ; \
+	(cd $(HOST_SUBDIR)/expat && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" \
+	          installcheck) \
+	  || exit 1
+
+@endif expat
+
+.PHONY: maybe-mostlyclean-expat mostlyclean-expat
+maybe-mostlyclean-expat:
+@if expat
+maybe-mostlyclean-expat: mostlyclean-expat
+
+mostlyclean-expat: 
+	@: $(MAKE); $(unstage)
+	@[ -f ./expat/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(HOST_EXPORTS) \
+	for flag in $(EXTRA_HOST_FLAGS) ; do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	echo "Doing mostlyclean in expat" ; \
+	(cd $(HOST_SUBDIR)/expat && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" \
+	          mostlyclean) \
+	  || exit 1
+
+@endif expat
+
+.PHONY: maybe-clean-expat clean-expat
+maybe-clean-expat:
+@if expat
+maybe-clean-expat: clean-expat
+
+clean-expat: 
+	@: $(MAKE); $(unstage)
+	@[ -f ./expat/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(HOST_EXPORTS) \
+	for flag in $(EXTRA_HOST_FLAGS) ; do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	echo "Doing clean in expat" ; \
+	(cd $(HOST_SUBDIR)/expat && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" \
+	          clean) \
+	  || exit 1
+
+@endif expat
+
+.PHONY: maybe-distclean-expat distclean-expat
+maybe-distclean-expat:
+@if expat
+maybe-distclean-expat: distclean-expat
+
+distclean-expat: 
+	@: $(MAKE); $(unstage)
+	@[ -f ./expat/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(HOST_EXPORTS) \
+	for flag in $(EXTRA_HOST_FLAGS) ; do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	echo "Doing distclean in expat" ; \
+	(cd $(HOST_SUBDIR)/expat && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" \
+	          distclean) \
+	  || exit 1
+
+@endif expat
+
+.PHONY: maybe-maintainer-clean-expat maintainer-clean-expat
+maybe-maintainer-clean-expat:
+@if expat
+maybe-maintainer-clean-expat: maintainer-clean-expat
+
+maintainer-clean-expat: 
+	@: $(MAKE); $(unstage)
+	@[ -f ./expat/Makefile ] || exit 0; \
+	r=`${PWD_COMMAND}`; export r; \
+	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+	$(HOST_EXPORTS) \
+	for flag in $(EXTRA_HOST_FLAGS) ; do \
+	  eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+	done; \
+	echo "Doing maintainer-clean in expat" ; \
+	(cd $(HOST_SUBDIR)/expat && \
+	  $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+	          "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+	          "RANLIB=$${RANLIB}" \
+	          "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" \
+	          maintainer-clean) \
+	  || exit 1
+
+@endif expat
+
+
+
 .PHONY: configure-fastjar maybe-configure-fastjar
 maybe-configure-fastjar:
 @if fastjar
@@ -38269,6 +38621,7 @@
 all-gdb: maybe-all-build-bison
 all-gdb: maybe-all-build-byacc
 all-gdb: maybe-all-sim
+all-gdb: maybe-all-expat
 configure-libgui: maybe-configure-tcl
 configure-libgui: maybe-configure-tk
 all-libgui: maybe-all-tcl
diff --git a/configure b/configure
index d74e611..3f7c571 100755
--- a/configure
+++ b/configure
@@ -886,7 +886,7 @@
 
 # these libraries are used by various programs built for the host environment
 #
-host_libs="intl mmalloc libiberty opcodes bfd readline tcl tk itcl libgui zlib libcpp libdecnumber"
+host_libs="intl mmalloc libiberty opcodes bfd readline tcl tk itcl libgui zlib libcpp libdecnumber expat"
 
 # these tools are built for the host environment
 # Note, the powerpc-eabi build depends on sim occurring before gdb in order to
diff --git a/configure.in b/configure.in
index adb53b9..f7c50c1 100644
--- a/configure.in
+++ b/configure.in
@@ -123,7 +123,7 @@
 
 # these libraries are used by various programs built for the host environment
 #
-host_libs="intl mmalloc libiberty opcodes bfd readline tcl tk itcl libgui zlib libcpp libdecnumber"
+host_libs="intl mmalloc libiberty opcodes bfd readline tcl tk itcl libgui zlib libcpp libdecnumber expat"
 
 # these tools are built for the host environment
 # Note, the powerpc-eabi build depends on sim occurring before gdb in order to
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 59280dc..d955c09 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -127,6 +127,10 @@
 READLINE_SRC = $(srcdir)/$(READLINE_DIR)
 READLINE_CFLAGS = -I$(READLINE_SRC)/..
 
+# Where is the expat library?  Typically in ../expat.
+EXPAT = ../expat/.libs/libexpat.a
+EXPAT_CFLAGS = -I$(srcdir)/../expat/lib -I../expat
+
 WARN_CFLAGS = @WARN_CFLAGS@
 WERROR_CFLAGS = @WERROR_CFLAGS@
 GDB_WARN_CFLAGS = $(WARN_CFLAGS)
@@ -350,6 +354,7 @@
 	$(CFLAGS) $(GLOBAL_CFLAGS) $(PROFILE_CFLAGS) \
 	$(GDB_CFLAGS) $(OPCODES_CFLAGS) $(READLINE_CFLAGS) \
 	$(BFD_CFLAGS) $(INCLUDE_CFLAGS) \
+	$(EXPAT_CFLAGS) \
 	$(INTL_CFLAGS) $(ENABLE_CFLAGS)
 INTERNAL_WARN_CFLAGS = $(INTERNAL_CFLAGS_BASE) $(GDB_WARN_CFLAGS)
 INTERNAL_CFLAGS = $(INTERNAL_WARN_CFLAGS) $(GDB_WERROR_CFLAGS)
@@ -378,9 +383,9 @@
 CLIBS = $(SIM) $(READLINE) $(OPCODES) $(BFD) $(INTL) $(LIBIBERTY) \
 	$(XM_CLIBS) $(TM_CLIBS) $(NAT_CLIBS) $(GDBTKLIBS) @LIBS@ \
 	$(LIBICONV) \
-	$(LIBIBERTY) $(WIN32LIBS)
+	$(LIBIBERTY) $(WIN32LIBS) $(EXPAT)
 CDEPS = $(XM_CDEPS) $(TM_CDEPS) $(NAT_CDEPS) $(SIM) $(BFD) $(READLINE) \
-	$(OPCODES) $(INTL_DEPS) $(LIBIBERTY) $(CONFIG_DEPS)
+	$(OPCODES) $(INTL_DEPS) $(LIBIBERTY) $(CONFIG_DEPS) $(EXPAT)
 
 ADD_FILES = $(XM_ADD_FILES) $(TM_ADD_FILES) $(NAT_ADD_FILES)
 ADD_DEPS = $(XM_ADD_FILES) $(TM_ADD_FILES) $(NAT_ADD_FILES)
@@ -390,11 +395,14 @@
 LINT=/usr/5bin/lint
 LINTFLAGS= $(GDB_CFLAGS) $(OPCODES_CFLAGS) $(READLINE_CFLAGS) \
 	$(BFD_CFLAGS) $(INCLUDE_CFLAGS) \
-	$(INTL_CFLAGS)
+	$(INTL_CFLAGS) $(EXPAT_CFLAGS)
 
 RUNTEST = runtest
 RUNTESTFLAGS=
 
+# XML files to build in to GDB.
+XMLFILES = $(srcdir)/features/gdb-target.dtd $(TDEP_XML)
+
 # This is ser-unix.o for any system which supports a v7/BSD/SYSV/POSIX
 # interface to the serial port.  Hopefully if get ported to OS/2, VMS,
 # etc., then there will be (as part of the C library or perhaps as
@@ -511,6 +519,7 @@
 # SFILES is used in building the distribution archive.
 
 SFILES = ada-exp.y ada-lang.c ada-typeprint.c ada-valprint.c  \
+	auxv.c available.c \
 	ax-general.c ax-gdb.c \
 	bcache.c \
 	bfd-target.c \
@@ -543,10 +552,12 @@
 	objfiles.c osabi.c observer.c \
 	p-exp.y p-lang.c p-typeprint.c p-valprint.c parse.c printcmd.c \
 	prologue-value.h \
+	parse-avail.c \
 	regcache.c reggroups.c remote.c remote-fileio.c \
 	scm-exp.c scm-lang.c scm-valprint.c \
 	sentinel-frame.c \
 	serial.c ser-base.c ser-unix.c \
+	sha1.c \
 	solib.c solib-null.c source.c \
 	stabsread.c stack.c std-regs.c symfile.c symfile-mem.c symmisc.c \
 	symtab.c \
@@ -602,6 +613,7 @@
 splay_tree_h =  $(INCLUDE_DIR)/splay-tree.h
 safe_ctype_h =  $(INCLUDE_DIR)/safe-ctype.h
 hashtab_h =	$(INCLUDE_DIR)/hashtab.h
+filenames_h =	$(INCLUDE_DIR)/filenames.h
 
 #
 # $BUILD/ headers
@@ -610,6 +622,7 @@
 config_h = config.h
 exc_request_U_h = exc_request_U.h
 exc_request_S_h = exc_request_S.h
+gdb_stdint_h = gdb_stdint.h
 msg_reply_S_h = msg_reply_S.h
 msg_U_h = msg_U.h
 notify_S_h = notify_S.h
@@ -639,6 +652,7 @@
 arch_utils_h = arch-utils.h
 arm_tdep_h = arm-tdep.h
 auxv_h = auxv.h
+available_h = available.h
 ax_gdb_h = ax-gdb.h
 ax_h = ax.h $(doublest_h)
 bcache_h = bcache.h
@@ -773,6 +787,7 @@
 ser_base_h = ser-base.h
 ser_tcp_h = ser-tcp.h
 ser_unix_h = ser-unix.h
+sha1_h = sha1.h $(gdb_stdint_h)
 shnbsd_tdep_h = shnbsd-tdep.h
 sh_tdep_h = sh-tdep.h
 sim_regno_h = sim-regno.h
@@ -789,7 +804,7 @@
 srec_h = srec.h
 stabsread_h = stabsread.h
 stack_h = stack.h
-symfile_h = symfile.h
+symfile_h = symfile.h $(symtab_h)
 symtab_h = symtab.h
 target_h = target.h $(bfd_h) $(symtab_h) $(dcache_h) $(memattr_h)
 terminal_h = terminal.h
@@ -905,6 +920,7 @@
 	version.o \
 	annotate.o \
 	auxv.o \
+	available.o parse-avail.o \
 	bfd-target.o \
 	blockframe.o breakpoint.o findvar.o regcache.o \
 	charset.o disasm.o dummy-frame.o \
@@ -936,6 +952,7 @@
 	m2-lang.o p-lang.o p-typeprint.o p-valprint.o \
 	scm-exp.o scm-lang.o scm-valprint.o \
 	sentinel-frame.o \
+	sha1.o \
 	complaints.o typeprint.o \
 	ada-typeprint.o c-typeprint.o f-typeprint.o m2-typeprint.o \
 	ada-valprint.o c-valprint.o cp-valprint.o f-valprint.o m2-valprint.o \
@@ -949,7 +966,8 @@
 	reggroups.o regset.o \
 	trad-frame.o \
 	tramp-frame.o \
-	solib.o solib-null.o
+	solib.o solib-null.o \
+	xml-builtin.o
 
 TSOBS = inflow.o
 
@@ -1260,6 +1278,7 @@
 	rm -f gdb$(EXEEXT) core make.log
 	rm -f gdb[0-9]$(EXEEXT)
 	rm -f test-cp-name-parser$(EXEEXT)
+	rm -f xml-builtin.c stamp-xml
 
 .PHONY: clean-tui
 clean-tui:
@@ -1277,6 +1296,7 @@
 	rm -f gdbserver/tm.h gdbserver/xm.h gdbserver/nm.h
 	rm -f gdbserver/Makefile gdbserver/config.cache
 	rm -f nm.h tm.h xm.h config.status config.h stamp-h .gdbinit
+	rm -f gdb_stdint.h
 	rm -f y.output yacc.acts yacc.tmp y.tab.h
 	rm -f config.log config.cache
 	rm -f Makefile
@@ -1314,15 +1334,31 @@
 	done
 
 Makefile: Makefile.in config.status @frags@
-	$(SHELL) config.status
+	# Regenerate the Makefile and the tm.h / nm.h links.
+	CONFIG_FILES=Makefile \
+	 CONFIG_COMMANDS= \
+	 CONFIG_HEADERS= \
+	 $(SHELL) config.status
 
 config.h: stamp-h ; @true
 stamp-h: config.in config.status
-	CONFIG_HEADERS=config.h:config.in $(SHELL) config.status
+	CONFIG_HEADERS=config.h:config.in \
+	 CONFIG_COMMANDS=default \
+	 CONFIG_FILES= \
+	 CONFIG_LINKS= \
+	 $(SHELL) config.status
 
 config.status: configure configure.tgt configure.host
 	$(SHELL) config.status --recheck
 
+gdb_stdint.h: stamp-int ; @true
+stamp-int: config.status
+	CONFIG_COMMANDS=gdb_stdint.h \
+	 CONFIG_FILES= \
+	 CONFIG_HEADERS= \
+	 CONFIG_LINKS= \
+	 $(SHELL) config.status
+	echo stamp > stamp-int
 force:
 
 # Documentation!
@@ -1649,6 +1685,17 @@
 .PRECIOUS: objc-exp.c
 .PRECIOUS: p-exp.c
 
+# XML rules
+
+xml-builtin.c: stamp-xml; @true
+stamp-xml: $(srcdir)/features/feature_to_c.sh Makefile $(XMLFILES)
+	rm -f xml-builtin.tmp
+	$(SHELL) $(srcdir)/features/feature_to_c.sh xml-builtin.tmp $(XMLFILES)
+	$(SHELL) $(srcdir)/../move-if-change xml-builtin.tmp xml-builtin.c
+	echo stamp > stamp-xml
+
+.PRECIOUS: xml-builtin.c
+
 #
 # gdb/ dependencies
 #
@@ -1763,10 +1810,14 @@
 	$(frame_unwind_h) $(frame_base_h) $(trad_frame_h) $(arm_tdep_h) \
 	$(gdb_sim_arm_h) $(elf_bfd_h) $(coff_internal_h) $(elf_arm_h) \
 	$(gdb_assert_h) $(bfd_in2_h) $(libcoff_h) $(objfiles_h) \
-	$(dwarf2_frame_h)
+	$(dwarf2_frame_h) $(available_h) $(user_regs_h)
 auxv.o: auxv.c $(defs_h) $(target_h) $(gdbtypes_h) $(command_h) \
 	$(inferior_h) $(valprint_h) $(gdb_assert_h) $(auxv_h) \
 	$(elf_common_h)
+available.o: available.c $(defs_h) $(symfile_h) $(target_h) $(available_h) \
+	$(arch_utils_h) $(exceptions_h) $(gdbtypes_h) $(sha1_h) \
+	$(reggroups_h) \
+	$(gdb_string) $(gdb_assert) $(gdb_obstack_h) $(gdb_stdint_h)
 avr-tdep.o: avr-tdep.c $(defs_h) $(frame_h) $(frame_unwind_h) \
 	$(frame_base_h) $(trad_frame_h) $(gdbcmd_h) $(gdbcore_h) \
 	$(inferior_h) $(symfile_h) $(arch_utils_h) $(regcache_h) \
@@ -1986,7 +2037,8 @@
 	$(gdb_assert_h)
 gdbarch.o: gdbarch.c $(defs_h) $(arch_utils_h) $(gdbcmd_h) $(inferior_h) \
 	$(symcat_h) $(floatformat_h) $(gdb_assert_h) $(gdb_string_h) \
-	$(gdb_events_h) $(reggroups_h) $(osabi_h) $(gdb_obstack_h)
+	$(gdb_events_h) $(reggroups_h) $(osabi_h) $(gdb_obstack_h) \
+	$(available_h)
 gdb.o: gdb.c $(defs_h) $(main_h) $(gdb_string_h) $(interps_h)
 gdb-events.o: gdb-events.c $(defs_h) $(gdb_events_h) $(gdbcmd_h)
 gdbtypes.o: gdbtypes.c $(defs_h) $(gdb_string_h) $(bfd_h) $(symtab_h) \
@@ -2130,7 +2182,7 @@
 	$(symfile_h) $(gdbcore_h) $(target_h) $(language_h) $(symfile_h) \
 	$(objfiles_h) $(completer_h) $(ui_out_h) $(event_top_h) \
 	$(parser_defs_h) $(regcache_h) $(reggroups_h) $(block_h) \
-	$(solib_h) $(gdb_assert_h) $(observer_h)
+	$(solib_h) $(gdb_assert_h) $(gdb_obstack_h) $(observer_h)
 inf-loop.o: inf-loop.c $(defs_h) $(inferior_h) $(target_h) $(event_loop_h) \
 	$(event_top_h) $(inf_loop_h) $(remote_h) $(exceptions_h)
 inflow.o: inflow.c $(defs_h) $(frame_h) $(inferior_h) $(command_h) \
@@ -2380,6 +2432,8 @@
 	$(frame_h) $(expression_h) $(value_h) $(command_h) $(language_h) \
 	$(parser_defs_h) $(gdbcmd_h) $(symfile_h) $(inferior_h) \
 	$(doublest_h) $(gdb_assert_h) $(block_h)
+parse-avail.o: parse-avail.c $(defs_h) $(available_h) $(gdb_assert_h) \
+	$(filenames_h) $(gdb_string) $(gdb_obstack_h) $(sha1_h)
 p-exp.o: p-exp.c $(defs_h) $(gdb_string_h) $(expression_h) $(value_h) \
 	$(parser_defs_h) $(language_h) $(p_lang_h) $(bfd_h) $(symfile_h) \
 	$(objfiles_h) $(block_h)
@@ -2456,7 +2510,7 @@
 	$(gdb_stabs_h) $(gdbthread_h) $(remote_h) $(regcache_h) $(value_h) \
 	$(gdb_assert_h) $(event_loop_h) $(event_top_h) $(inf_loop_h) \
 	$(serial_h) $(gdbcore_h) $(remote_fileio_h) $(solib_h) $(observer_h) \
-	$(cli_decode_h) $(cli_setshow_h)
+	$(cli_decode_h) $(cli_setshow_h) $(available_h)
 remote-e7000.o: remote-e7000.c $(defs_h) $(gdbcore_h) $(gdbarch_h) \
 	$(inferior_h) $(target_h) $(value_h) $(command_h) $(gdb_string_h) \
 	$(exceptions_h) $(gdbcmd_h) $(serial_h) $(remote_utils_h) \
@@ -2537,6 +2591,7 @@
 	$(terminal_h) $(gdb_select_h) $(gdb_string_h)
 ser-mingw.o: ser-mingw.c $(defs_h) $(serial_h) $(ser_base_h) \
 	$(ser_tcp_h) $(gdb_assert_h) $(gdb_string_h)
+sha1.o: sha1.c $(config_h) $(sha1_h)
 sh3-rom.o: sh3-rom.c $(defs_h) $(gdbcore_h) $(target_h) $(monitor_h) \
 	$(serial_h) $(srec_h) $(arch_utils_h) $(regcache_h) $(gdb_string_h) \
 	$(sh_tdep_h)
diff --git a/gdb/README.AVAIL b/gdb/README.AVAIL
new file mode 100644
index 0000000..a246de7
--- /dev/null
+++ b/gdb/README.AVAIL
@@ -0,0 +1,203 @@
+Notes for the branch "gdb-csl-available-20060303-branch"
+--------------------------------------------------------
+
+This branch implements a new mechanism which allows GDB to ask a target
+"what features do you have?" GDB can then interpret the response and
+dynamically present those features to the user.  Some features require
+corresponding support in GDB, and must be specially recognized by the target
+architecture.  Others do not require additional GDB support, e.g. additional
+registers (the only type of feature implemented so far).
+
+The branch does not have a ChangeLog relative to mainline; one will be written
+later.  So far, only the ARM target has any support for available features.
+
+The most interesting portion of this document is the TODO list; the rest may
+get somewhat out of date.
+
+Control flow in GDB
+-------------------
+
+After connecting to the target, we check the new architecture-provided setting
+gdbarch_available_features_support.  If it is set, we query the target
+for its available features, interpret the response, and switch to a new
+gdbarch, derived from the current one, with these features recorded.
+
+In order for the derivation process to work, the architecture's gdbarch_init
+must correctly support filling in defaults based on the last used architecture.
+If it does not, for example, cache something read from the ELF binary in
+gdbarch_tdep, the architecture is likely to get out of sync with the
+debuggee.
+
+During debugging, GDB can query information from the current set of
+features.  This is currently done in architecture-specific hooks, but may be
+done in common code in the future.
+
+Writing a feature description
+-----------------------------
+
+Feature descriptions are written in XML.  The current DTD is in
+gdb/features/gdb-target.dtd.  There are some limits beyond those
+expressed in the DTD - many of these limits are not yet documented
+and not yet relevant until additional GDB support has been implemented.
+See the TODO.
+
+Here's a simple sample description:
+
+<?xml version="1.0"?>
+<!DOCTYPE target SYSTEM "gdb-target.dtd">
+<target>
+  <feature name="bar">
+    <reg name="s0" bitsize="32"/>
+    <reg name="s1" bitsize="32" type="float"/>
+  </feature>
+
+  <feature-set>
+    <feature-ref name="bar" base-regnum="1"/>
+  </feature-set>
+</target>
+
+This describes a simple target feature set which only contains two registers,
+named s0 (32-bit, integer) and s1 (32-bit, floating point).
+
+You can spread a description over multiple files by using the standardized
+XInclude mechanism - but only whole-file XInclude is supported.  The
+xpointer attribute should not be used, and the href attribute should be,
+using a bare basename.  GDB will query the target for the file, if it has
+not already seen it.
+
+You can validate the description using any XML validator which supports XInclude.
+For instance, with "xmllint" (shipped as part of the GNOME libxml2 package):
+
+	xmllint --xinclude --postvalid my-target.xml
+
+Post validation is usually appropriate when using XInclude; the DTD describes
+the document after XInclude processing.
+
+GDB fetches CHECKSUMS initially.  Files with a listed checksum may be
+fetched from a cache instead of from the target (currently only RAM caching
+is implemented).  Next, GDB fetches "target.xml", and then any files
+included using XInclude.  Files not listed in CHECKSUMS will not be fetched
+from the cache - they may be e.g. generated on the fly.  The target
+description is fetched on connect, and again after application restart in
+case it has changed (TODO: is this wasteful, should it be fetched only
+once?  This only matters for target extended-remote, so it isn't a big
+deal right now.)
+
+By default, feature names must be unique within the document (XML "ID"
+constraint), but not globally unique.  However, GDB must recognize some
+features explicitly to enable additional support for them.  It uses the
+feature name to detect their presence.  These features should have
+unambiguous, globally unique names.  If the feature is described in the GDB
+manual, use the name listed there.  If not, and you are adding code to a
+local version of GDB to recognize the feature by name, please use a name
+which includes your organization.  For instance, "org.gnu.gdb.arm.core", or
+"com.codesourcery.foovendor.coproc". This method prevents conflicts with
+other names chosen by other groups.
+
+The target description should specify every register provided by the
+target, including the GDB standard ones.
+
+
+TODO items and unsettled (or unasked) questions
+-----------------------------------------------
+
+When finished this documentation needs to move into the user and internals
+manual.
+
+The "ro" and "save-restore" tags may not express enough information about
+how to treat system registers.  Richard Earnshaw suggested a more detailed
+categorization; I need to consider it; I think it's a good idea at first
+glance.
+
+Reading and writing registers using the 'p' and 'P' packets is very
+inefficient; a target mechanism and remote protocol packets for multiple
+register batching would probably help a lot.  Note, the branch now does a
+simple subset of this assuming a reasonable 'g' packet.
+
+For ARM VFP, there are two views of some registers: s0 / s1 are single precision
+registers overlayed in storage with d0, a double precision register.  Many
+other targets do the same thing.  Should we express this to GDB, or just
+allow it to read them both from the target (somewhat wasteful)?  GDB already
+assumes that modifying one register may modify another unpredictably, so
+writing is OK - the only problem is a waste of bandwidth.
+
+The DTD allows for description fields, including multi-lingual ones, but
+there is no GDB support for descriptions.  It would be good to present
+them to the user.
+
+Should we convey the information read from the target (after e.g. XInclude
+processing) to MI front ends, or are the changes to the register cache
+sufficient?  For instance, Eclipse would probably be happy to display most
+of this data (especially descriptions).  I think there should be one MI
+command to fetch the DTD used, and another to fetch the description used. 
+XInclude processing has been moved into a separate phase to facilitate this.
+Because other external entities are not supported, these two are guaranteed
+to convey the entire description.
+
+The current DTD and GDB support does not allow for nested features.  This
+is probably useful.  I think this will be a must-have in the long term.
+
+GDB needs additional error checking for its assumptions of unique names.
+For instance, there may be multiple registers with the same name in
+GDB's feature database, but they had better not be instantiated in
+the same feature set.
+
+Should known features be compiled in to GDB, or loaded from the filesystem?
+The most essential features should probably be compiled in, so that the GDB
+binary is useful standalone.  The DTD is already compiled in, but there's no
+support for a target to supply default features by XML instead of hand
+coding.
+
+GDB should support reading features and feature sets from disk instead of
+from the target.
+
+GDB should support caching features read from the target in a user-specified
+directory.
+
+Should GDB warn about unrecognized features which require additional GDB
+support, or silently ignore them?  Currently there is no way to detect
+this.  It's not a big deal.
+
+Since the name field of features may be hierarchical, and the description is
+free-form (more like "help text"), there should probably be a "short
+description" field - a user label without the uniqueness constraint.
+
+Another suggested type of feature is a memory map - which areas of memory
+the debugger may read from / write to.
+
+Targets could use XML to supply their default feature set.  It's nice in that
+it moves a bit of code from the tdep files out into a description file; but
+less nice in that it might lose flexibility that we need; the target might
+have to run-time generate the XML.  Currently there are no plans to require
+this, but it may turn out to be a simplifying assumption later.
+
+Register group handling right now is somewhat simplistic; only
+group="general", group="float", group="vector", and no explicit group
+setting (use type to categorize) are supported.  We could extend this, or
+we could limit it to those and provide an alternate hierarchy based on
+the containing features.
+
+Eventually supporting multiple instances of a feature is desirable. This
+requires some instance-name on the feature reference, and using that to
+prefix the registers for that feature.  Maybe treat the registers as a large
+struct.  This would be sort of useful anyway, to avoid clobbering
+the convenience variable namespace.  Maybe only "core" registers should
+be in the default namespace?  Maybe key that off the description, empty
+or missing instance-name -> default namespace?
+
+In the mean time, GDB should check for duplicated register names, and
+warn that it can not support them.
+
+Should hardware MMIO registers be treated as registers, or as memory, or
+using new read/write packets that can guarantee appropriate I/O width?
+If as registers, we need to be careful with ones where reading them
+triggers an action (e.g. resetting some state).
+
+A nice-to-have item would be a basic architecture identifier:
+  (gdb) target remote board:2345
+  warning: This GDB does not support the "arm" architecture.
+
+Should the current extended-remote be changed from a client-requested
+property ("!" packet) to a target-announced property?  Some stubs
+should always be used in extended mode, some don't support it.  Some
+get by with either, but usually, not very well.
diff --git a/gdb/acinclude.m4 b/gdb/acinclude.m4
index 3bc60e4..d905bf3 100644
--- a/gdb/acinclude.m4
+++ b/gdb/acinclude.m4
@@ -14,6 +14,8 @@
 AC_DEFUN([CY_GNU_GETTEXT],)
 ])
 
+sinclude(../config/stdint.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])
diff --git a/gdb/aclocal.m4 b/gdb/aclocal.m4
index ecb2ae1..89a8eac 100644
--- a/gdb/aclocal.m4
+++ b/gdb/aclocal.m4
@@ -1,7 +1,7 @@
-# generated automatically by aclocal 1.9.2 -*- Autoconf -*-
+# generated automatically by aclocal 1.9.6 -*- Autoconf -*-
 
-# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
-# Free Software Foundation, Inc.
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+# 2005  Free Software Foundation, Inc.
 # This file 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.
@@ -11,26 +11,16 @@
 # even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 # PARTICULAR PURPOSE.
 
-# AM_CONDITIONAL                                              -*- Autoconf -*-
+# AM_CONDITIONAL                                            -*- Autoconf -*-
 
-# Copyright (C) 1997, 2000, 2001, 2003, 2004 Free Software Foundation, Inc.
+# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005
+# Free Software Foundation, Inc.
+#
+# This file 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 free software; you can redistribute 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 6
+# serial 7
 
 # AM_CONDITIONAL(NAME, SHELL-CONDITION)
 # -------------------------------------
@@ -54,28 +44,17 @@
 Usually this means the macro was only invoked conditionally.]])
 fi])])
 
-# Add --enable-maintainer-mode option to configure.
+# Add --enable-maintainer-mode option to configure.         -*- Autoconf -*-
 # From Jim Meyering
 
-# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004
+# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005
 # Free Software Foundation, Inc.
+#
+# This file 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 free software; you can redistribute 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 3
+# serial 4
 
 AC_DEFUN([AM_MAINTAINER_MODE],
 [AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index 54d1bcc..25a5416 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -41,6 +41,8 @@
 #include "objfiles.h"
 #include "dwarf2-frame.h"
 #include "prologue-value.h"
+#include "available.h"
+#include "user-regs.h"
 
 #include "arm-tdep.h"
 #include "gdb/sim-arm.h"
@@ -806,13 +808,15 @@
 	  imm = (imm >> rot) | (imm << (32 - rot));
 	  sp_offset -= imm;
 	}
-      else if ((insn & 0xffff7fff) == 0xed6d0103)	/* stfe f?, [sp, -#c]! */
+      else if ((insn & 0xffff7fff) == 0xed6d0103	/* stfe f?, [sp, -#c]! */
+	       && gdbarch_tdep (current_gdbarch)->have_fpa_registers)
 	{
 	  sp_offset -= 12;
 	  regno = ARM_F0_REGNUM + ((insn >> 12) & 0x07);
 	  cache->saved_regs[regno].addr = sp_offset;
 	}
-      else if ((insn & 0xffbf0fff) == 0xec2d0200)	/* sfmfd f0, 4, [sp!] */
+      else if ((insn & 0xffbf0fff) == 0xec2d0200	/* sfmfd f0, 4, [sp!] */
+	       && gdbarch_tdep (current_gdbarch)->have_fpa_registers)
 	{
 	  int n_saved_fp_regs;
 	  unsigned int fp_start_reg, fp_bound_reg;
@@ -1351,8 +1355,21 @@
 static struct type *
 arm_register_type (struct gdbarch *gdbarch, int regnum)
 {
+  struct type *avail_type;
+
+  avail_type = available_register_type (gdbarch, regnum);
+  if (avail_type)
+    return avail_type;
+
+  if (gdbarch_tdep (current_gdbarch)->have_vfp_pseudos
+      && regnum >= NUM_REGS && regnum < NUM_REGS + 32)
+    return builtin_type_float;
+
   if (regnum >= ARM_F0_REGNUM && regnum < ARM_F0_REGNUM + NUM_FREGS)
     {
+      if (!gdbarch_tdep (gdbarch)->have_fpa_registers)
+	return builtin_type_void;
+
       if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
 	return builtin_type_arm_ext_big;
       else
@@ -1362,21 +1379,54 @@
     return builtin_type_int32;
 }
 
-/* Index within `registers' of the first byte of the space for
-   register N.  */
-
+/* Map DWARF register numbers onto internal GDB register numbers.  */
 static int
-arm_register_byte (int regnum)
+arm_dwarf_reg_to_regnum (int reg)
 {
-  if (regnum < ARM_F0_REGNUM)
-    return regnum * INT_REGISTER_SIZE;
-  else if (regnum < ARM_PS_REGNUM)
-    return (NUM_GREGS * INT_REGISTER_SIZE
-	    + (regnum - ARM_F0_REGNUM) * FP_REGISTER_SIZE);
-  else
-    return (NUM_GREGS * INT_REGISTER_SIZE
-	    + NUM_FREGS * FP_REGISTER_SIZE
-	    + (regnum - ARM_FPS_REGNUM) * STATUS_REGISTER_SIZE);
+  /* Core integer regs.  */
+  if (reg >= 0 && reg <= 15)
+    return reg;
+
+  /* Legacy FPA encoding.  These were once used in a way which
+     overlapped with VFP register numbering, so their use is
+     discouraged, but GDB doesn't support the ARM toolchain
+     which did that.  */
+  if (reg >= 16 && reg <= 23)
+    return ARM_F0_REGNUM + reg - 16;
+
+  /* New assignments for the FPA registers.  */
+  if (reg >= 96 && reg <= 103)
+    return ARM_F0_REGNUM + reg - 96;
+
+  /* VFP v2 registers.  A double precision value is actually
+     in d1 rather than s2, but the ABI only defines numbering
+     for the single precision registers.  This will "just work"
+     in GDB for little endian targets (we'll read eight bytes,
+     starting in s0 and then progressing to s1), but will be
+     reversed on big endian targets with VFP.  This won't
+     be a problem for the new Neon quad registers; you're supposed
+     to use DW_OP_piece for those.  */
+  if (reg >= 64 && reg <= 95)
+    {
+      char name_buf[4];
+
+      sprintf (name_buf, "s%d", reg - 64);
+      return user_reg_map_name_to_regnum (current_gdbarch, name_buf,
+					  strlen (name_buf));
+    }
+
+  /* VFP v3 / Neon registers.  This range is also used for VFP v2
+     registers, except that it now describes d0 instead of s0.  */
+  if (reg >= 256 && reg <= 287)
+    {
+      char name_buf[4];
+
+      sprintf (name_buf, "d%d", reg - 256);
+      return user_reg_map_name_to_regnum (current_gdbarch, name_buf,
+					  strlen (name_buf));
+    }
+
+  return -1;
 }
 
 /* Map GDB internal REGNUM onto the Arm simulator register numbers.  */
@@ -2474,7 +2524,35 @@
 static const char *
 arm_register_name (int i)
 {
-  return arm_register_names[i];
+  const char *avail_name;
+
+  /* Allow arm_register_names to override the names for standard
+     registers from the target, for "set arm disassembler".  */
+  if (i <= ARM_PC_REGNUM || i == ARM_PS_REGNUM)
+    return arm_register_names[i];
+  if (i <= ARM_FPS_REGNUM)
+    {
+      if (gdbarch_tdep (current_gdbarch)->have_fpa_registers)
+	return arm_register_names[i];
+      else
+	return "";
+    }
+
+  if (gdbarch_tdep (current_gdbarch)->have_vfp_pseudos
+      && i >= NUM_REGS && i < NUM_REGS + 32)
+    {
+      static const char *const vfp_pseudo_names[] = {
+	"s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
+	"s8", "s9", "s10", "s11", "s12", "s13", "s14", "s15",
+	"s16", "s17", "s18", "s19", "s20", "s21", "s22", "s23",
+	"s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
+      };
+
+      return vfp_pseudo_names[i - NUM_REGS];
+    }
+
+  /* Check for target-supplied register numbers.  */
+  return available_register_name (current_gdbarch, i);
 }
 
 static void
@@ -2577,6 +2655,57 @@
     }
 #endif
 }
+
+static void
+arm_pseudo_vfp_read (struct gdbarch *gdbarch, struct regcache *regcache,
+		     int regnum, gdb_byte *buf)
+{
+  char name_buf[4];
+  gdb_byte reg_buf[8];
+  int offset, double_regnum;
+
+  gdb_assert (regnum >= NUM_REGS && regnum <= NUM_REGS + 32);
+  regnum -= NUM_REGS;
+
+  /* s0 is always the least significant half of d0.  */
+  if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+    offset = (regnum & 1) ? 0 : 4;
+  else
+    offset = (regnum & 1) ? 4 : 0;
+
+  sprintf (name_buf, "d%d", regnum >> 1);
+  double_regnum = user_reg_map_name_to_regnum (gdbarch, name_buf,
+					       strlen (name_buf));
+
+  regcache_raw_read (regcache, double_regnum, reg_buf);
+  memcpy (buf, reg_buf + offset, 4);
+}
+
+static void
+arm_pseudo_vfp_write (struct gdbarch *gdbarch, struct regcache *regcache,
+		      int regnum, const gdb_byte *buf)
+{
+  char name_buf[4];
+  gdb_byte reg_buf[8];
+  int offset, double_regnum;
+
+  gdb_assert (regnum >= NUM_REGS && regnum <= NUM_REGS + 32);
+  regnum -= NUM_REGS;
+
+  /* s0 is always the least significant half of d0.  */
+  if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+    offset = (regnum & 1) ? 0 : 4;
+  else
+    offset = (regnum & 1) ? 4 : 0;
+
+  sprintf (name_buf, "d%d", regnum >> 1);
+  double_regnum = user_reg_map_name_to_regnum (gdbarch, name_buf,
+					       strlen (name_buf));
+
+  regcache_raw_read (regcache, double_regnum, reg_buf);
+  memcpy (reg_buf + offset, buf, 4);
+  regcache_raw_write (regcache, double_regnum, reg_buf);
+}
 
 static enum gdb_osabi
 arm_elf_osabi_sniffer (bfd *abfd)
@@ -2597,6 +2726,72 @@
   return osabi;
 }
 
+static void
+arm_require_register (struct gdb_feature_set *feature_set,
+		      const char *name, int regnum)
+{
+  if (!available_find_named_register (feature_set, name, regnum))
+    error (_("target does not provide required register \"%s\""), name);
+}
+
+static void
+arm_check_feature_set (struct gdbarch *gdbarch,
+		       struct gdb_feature_set *feature_set)
+{
+  static const char *const arm_standard_names[] =
+    {
+      "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+      "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+      "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "fps",
+      "cpsr"
+    };
+  int i;
+
+  if (!available_find_named_feature (feature_set, "org.gnu.gdb.arm.core"))
+    error (_("target does not provide ARM core registers"));
+
+  for (i = 0; i < 16; i++)
+    arm_require_register (feature_set, arm_standard_names[i], i);
+
+  arm_require_register (feature_set, arm_standard_names[ARM_PS_REGNUM],
+			ARM_PS_REGNUM);
+
+  /* If we have an FPA unit, require the FPA registers and assign them
+     fixed numbers.  If we don't have FPA, these register numbers will
+     remain unused, since various ARM subtargets hardcode the
+     numbering.  */
+
+  if (available_find_named_feature (feature_set, "org.gnu.gdb.arm.fpa"))
+    {
+      for (i = ARM_F0_REGNUM; i <= ARM_FPS_REGNUM; i++)
+	arm_require_register (feature_set, arm_standard_names[i], i);
+      gdbarch_tdep (gdbarch)->have_fpa_registers = 1;
+    }
+  else
+    gdbarch_tdep (gdbarch)->have_fpa_registers = 0;
+
+  /* If we have a VFP unit, check whether the single precision registers
+     are present.  If not, then we will synthesize them as pseudo
+     registers.  */
+
+  if (available_find_named_feature (feature_set, "org.gnu.gdb.arm.vfp"))
+    {
+      if (available_find_named_register (feature_set, "d0", -1)
+	  && !available_find_named_register (feature_set, "s0", -1))
+	{
+	  /* NOTE: This is the only set of pseudo registers used by
+	     the ARM target at the moment.  If more are added, a
+	     little more care in numbering will be needed.  */
+
+	  set_gdbarch_num_pseudo_regs (gdbarch, 32);
+	  set_gdbarch_pseudo_register_read (gdbarch, arm_pseudo_vfp_read);
+	  set_gdbarch_pseudo_register_write (gdbarch, arm_pseudo_vfp_write);
+	  gdbarch_tdep (gdbarch)->have_vfp_pseudos = 1;
+	}
+      gdbarch_tdep (gdbarch)->have_vfp_registers = 1;
+    }
+}
+
 
 /* Initialize the current architecture based on INFO.  If possible,
    re-use an architecture from ARCHES, which is a list of
@@ -2788,15 +2983,31 @@
   set_gdbarch_breakpoint_from_pc (gdbarch, arm_breakpoint_from_pc);
 
   /* Information about registers, etc.  */
-  set_gdbarch_print_float_info (gdbarch, arm_print_float_info);
   set_gdbarch_deprecated_fp_regnum (gdbarch, ARM_FP_REGNUM);	/* ??? */
   set_gdbarch_sp_regnum (gdbarch, ARM_SP_REGNUM);
   set_gdbarch_pc_regnum (gdbarch, ARM_PC_REGNUM);
-  set_gdbarch_deprecated_register_byte (gdbarch, arm_register_byte);
   set_gdbarch_num_regs (gdbarch, NUM_GREGS + NUM_FREGS + NUM_SREGS);
   set_gdbarch_register_type (gdbarch, arm_register_type);
+  set_gdbarch_register_reggroup_p (gdbarch, available_register_reggroup_p);
+
+  if (info.feature_set)
+    {
+      arm_check_feature_set (gdbarch, info.feature_set);
+      record_available_features (gdbarch, info.feature_set);
+    }
+  else
+    /* The legacy layout of the remote "g" packet assumes we have
+       the FPA registers, as do some native targets.  */
+    gdbarch_tdep (gdbarch)->have_fpa_registers = 1;
+
+  /* This "info float" is FPA-specific.  Use the generic version if we
+     do not have FPA.  */
+  if (gdbarch_tdep (gdbarch)->have_fpa_registers)
+    set_gdbarch_print_float_info (gdbarch, arm_print_float_info);
 
   /* Internal <-> external register number maps.  */
+  set_gdbarch_dwarf_reg_to_regnum (gdbarch, arm_dwarf_reg_to_regnum);
+  set_gdbarch_dwarf2_reg_to_regnum (gdbarch, arm_dwarf_reg_to_regnum);
   set_gdbarch_register_sim_regno (gdbarch, arm_register_sim_regno);
 
   /* Integer registers are 4 bytes.  */
@@ -2863,6 +3074,8 @@
 		      _("arm_gdbarch_init: bad byte order for float format"));
     }
 
+  set_gdbarch_available_features_support (gdbarch, 1);
+
   return gdbarch;
 }
 
diff --git a/gdb/arm-tdep.h b/gdb/arm-tdep.h
index 3141052..33e9b6c 100644
--- a/gdb/arm-tdep.h
+++ b/gdb/arm-tdep.h
@@ -131,6 +131,11 @@
 
   enum arm_float_model fp_model; /* Floating point calling conventions.  */
 
+  int have_fpa_registers;	/* Does the target report the FPA registers?  */
+  int have_vfp_registers;	/* Does the target report the VFP registers?  */
+  int have_vfp_pseudos;		/* Are we synthesizing the single precision
+				   VFP registers?  */
+
   CORE_ADDR lowest_pc;		/* Lowest address at which instructions 
 				   will appear.  */
 
diff --git a/gdb/auxv.c b/gdb/auxv.c
index 557da3d..8a2c9fc 100644
--- a/gdb/auxv.c
+++ b/gdb/auxv.c
@@ -76,43 +76,6 @@
   return n;
 }
 
-/* Read all the auxv data into a contiguous xmalloc'd buffer,
-   stored in *DATA.  Return the size in bytes of this data.
-   If zero, there is no data and *DATA is null.
-   if < 0, there was an error and *DATA is null.  */
-LONGEST
-target_auxv_read (struct target_ops *ops, gdb_byte **data)
-{
-  size_t auxv_alloc = 512, auxv_pos = 0;
-  gdb_byte *auxv = xmalloc (auxv_alloc);
-  int n;
-
-  while (1)
-    {
-      n = target_read_partial (ops, TARGET_OBJECT_AUXV,
-			       NULL, &auxv[auxv_pos], 0,
-			       auxv_alloc - auxv_pos);
-      if (n <= 0)
-	break;
-      auxv_pos += n;
-      if (auxv_pos < auxv_alloc) /* Read all there was.  */
-	break;
-      gdb_assert (auxv_pos == auxv_alloc);
-      auxv_alloc *= 2;
-      auxv = xrealloc (auxv, auxv_alloc);
-    }
-
-  if (auxv_pos == 0)
-    {
-      xfree (auxv);
-      *data = NULL;
-      return n;
-    }
-
-  *data = auxv;
-  return auxv_pos;
-}
-
 /* Read one auxv entry from *READPTR, not reading locations >= ENDPTR.
    Return 0 if *READPTR is already at the end of the buffer.
    Return -1 if there is insufficient buffer for a whole entry.
@@ -148,7 +111,7 @@
 {
   CORE_ADDR type, val;
   gdb_byte *data;
-  int n = target_auxv_read (ops, &data);
+  LONGEST n = target_read_whole (ops, TARGET_OBJECT_AUXV, NULL, &data);
   gdb_byte *ptr = data;
   int ents = 0;
 
@@ -184,7 +147,7 @@
 {
   CORE_ADDR type, val;
   gdb_byte *data;
-  int len = target_auxv_read (ops, &data);
+  LONGEST len = target_read_whole (ops, TARGET_OBJECT_AUXV, NULL, &data);
   gdb_byte *ptr = data;
   int ents = 0;
 
diff --git a/gdb/auxv.h b/gdb/auxv.h
index 92f7b54..c3030b0 100644
--- a/gdb/auxv.h
+++ b/gdb/auxv.h
@@ -31,12 +31,6 @@
 struct target_ops;		/* Forward declaration.  */
 
 
-/* Read all the auxv data into a contiguous xmalloc'd buffer,
-   stored in *DATA.  Return the size in bytes of this data.
-   If zero, there is no data and *DATA is null.
-   if < 0, there was an error and *DATA is null.  */
-extern LONGEST target_auxv_read (struct target_ops *ops, gdb_byte **data);
-
 /* Read one auxv entry from *READPTR, not reading locations >= ENDPTR.
    Return 0 if *READPTR is already at the end of the buffer.
    Return -1 if there is insufficient buffer for a whole entry.
diff --git a/gdb/available.c b/gdb/available.c
new file mode 100644
index 0000000..d6ccbc1
--- /dev/null
+++ b/gdb/available.c
@@ -0,0 +1,726 @@
+/* Support for runtime-defined target features for GDB.
+
+   Copyright (C) 2006
+   Free Software Foundation, Inc.
+
+   Contributed by CodeSourcery.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
+
+#include "defs.h"
+#include "arch-utils.h"
+#include "exceptions.h"
+#include "gdbtypes.h"
+#include "reggroups.h"
+#include "symfile.h"
+#include "target.h"
+#include "sha1.h"
+
+#include "available.h"
+
+#include "gdb_assert.h"
+#include "gdb_string.h"
+#include "gdb_obstack.h"
+#include "gdb_stdint.h"
+
+/* TODO: Remote target "guess" features from g packet size */
+
+/* TODO: Clarify warning messages.  Remember, they will appear to
+   the user with no context after a "target remote".  The user
+   doesn't know how we got into this code.  */
+
+/* Architecture TODO to support this:
+
+   - Call available_register_type from _register_type method.
+   - Handle unexpected changes to _num_regs.
+   - Call record_available_features from _gdbarch_init.
+   - Do not override the default _register_byte
+
+  (WARNING: This list is out of date and should be redone before submission.
+  And moved into gdbint.texi.)
+*/
+
+
+
+/* Support for caching XML objects read from the target.
+
+   TODO ITEMS:
+   - Support caching to disk.
+   - Support compiled-in feature cache.
+   - Figure out memory management for feature contents strings.
+*/
+
+
+/* Saved information about cached XML objects.  Each cache entry
+   corresponds to a file in the cache, or an object fetched from
+   the target with one particular annex.  */
+
+struct xml_cache_entry
+{
+  const char *annex;
+  const char *contents;
+
+  /* This flag is cleared when we begin reading features, and set
+     for new features when they are read.  It is used to prevent
+     reading the same file from the target twice (for multiple
+     xi:include's or DTD references).  */
+  int recently_used;
+
+  union
+  {
+    /* We use a union to represent the checksum in order to guarantee
+       sufficient alignment.  */
+    uint32_t words[5];
+    unsigned char bytes[20];
+  } sha1sum;
+
+  struct xml_cache_entry *next;
+};
+
+/* A list of all the cached objects.  */
+
+static struct xml_cache_entry *xml_global_cache;
+
+/* Look for a feature in the cache with ANNEX and CHECKSUM.  If
+   CHECKSUM is NULL, then look for a feature in the cache which has
+   already been used this session.  If no entry is found, return
+   NULL.  */
+
+static const char *
+find_xml_feature_in_cache (const char *annex, const unsigned char *checksum)
+{
+  struct xml_cache_entry *ent;
+
+  for (ent = xml_global_cache; ent != NULL; ent = ent->next)
+    {
+      if (strcmp (ent->annex, annex) != 0)
+	continue;
+
+      if (checksum == NULL && !ent->recently_used)
+	continue;
+
+      if (checksum != NULL && memcmp (ent->sha1sum.bytes, checksum, 20) != 0)
+	continue;
+
+      ent->recently_used = 1;
+      return ent->contents;
+    }
+
+  return NULL;
+}
+
+/* Add CONTENTS, which represents the object named ANNEX, to the
+   cache if it is not already cached.  */
+
+static void
+add_xml_feature_to_cache (const char *annex, const char *contents)
+{
+  struct xml_cache_entry new_ent;
+
+  /* FIXME: Again, memory allocation?  */
+  new_ent.annex = xstrdup (annex);
+  new_ent.contents = xstrdup (contents);
+
+  sha1_buffer (new_ent.contents, strlen (new_ent.contents),
+	       new_ent.sha1sum.bytes);
+
+  /* If this entry is already in the cache, do not add it again.  This
+     call also marks the cache entry as used.  */
+  if (find_xml_feature_in_cache (annex, new_ent.sha1sum.bytes))
+    return;
+
+  new_ent.recently_used = 1;
+  new_ent.next = xml_global_cache;
+
+  xml_global_cache = xmalloc (sizeof (struct xml_cache_entry));
+  memcpy (xml_global_cache, &new_ent, sizeof (struct xml_cache_entry));
+}
+
+/* Convert an ASCII checksum string, CHECKSUM, to a binary blob,
+   BYTES.  Returns 0 for success, or -1 if a bad character is
+   encountered.  CHECKSUM does not need to be NUL terminated.  */
+
+static int
+checksum_to_bytes (char *checksum, unsigned char *bytes)
+{
+  int i;
+
+  for (i = 0; i < 20; i++)
+    {
+      int n;
+      char c1, c2;
+
+      c1 = checksum[2 * i];
+      if (c1 >= '0' && c1 <= '9')
+	n = c1 - '0';
+      else if (c1 >= 'a' && c1 <= 'f')
+	n = c1 - 'a' + 10;
+      else if (c1 >= 'A' && c1 <= 'F')
+	n = c1 - 'A' + 10;
+      else
+	return -1;
+
+      n *= 16;
+
+      c2 = checksum[2 * i + 1];
+      if (c2 >= '0' && c2 <= '9')
+	n += c2 - '0';
+      else if (c2 >= 'a' && c2 <= 'f')
+	n += c2 - 'a' + 10;
+      else if (c2 >= 'A' && c2 <= 'F')
+	n += c2 - 'A' + 10;
+      else
+	return -1;
+
+      bytes[i] = n;
+    }
+
+  return 0;
+}
+
+/* Baton passed to fetch_available_features_from_target.  */
+
+struct fetch_features_baton
+{
+  struct target_ops *ops;
+
+  struct fetch_features_checksum
+  {
+    const char *annex;
+    unsigned char checksum[20];
+  } *checksums;
+};
+
+/* Read a string representation of available features from the target,
+   using TARGET_OBJECT_AVAILABLE_FEATURES.  The returned string is
+   malloc allocated and NUL-terminated.  NAME should be a non-NULL
+   string identifying the XML document we want; the top level document
+   is "target.xml".  Other calls may be performed for the DTD or
+   for xi:include.  */
+
+static char *
+fetch_available_features_from_target (const char *name, void *baton_)
+{
+  struct fetch_features_baton *baton = baton_;
+  char *features_str;
+  gdb_byte *features_buf;
+  LONGEST len;
+  const unsigned char *checksum = NULL;
+  const char *cached_str;
+
+  if (baton->checksums)
+    {
+      struct fetch_features_checksum *checksum_ent;
+
+      for (checksum_ent = baton->checksums;
+	   checksum_ent->annex != NULL;
+	   checksum_ent++)
+	if (strcmp (checksum_ent->annex, name) == 0)
+	  break;
+
+      if (checksum_ent->annex)
+	checksum = checksum_ent->checksum;
+    }
+
+  cached_str = find_xml_feature_in_cache (name, checksum);
+
+  /* This function always returns something which the caller is
+     responsible for freeing.  So, if we got a match, return a
+     copy of it.  */
+  if (cached_str)
+    return xstrdup (cached_str);
+
+  len = target_read_whole (baton->ops, TARGET_OBJECT_AVAILABLE_FEATURES,
+			   name, &features_buf);
+  if (len <= 0)
+    return NULL;
+
+  /* Since we decode this object as a string, simplify processing by
+     making sure it is NUL terminated.  */
+  features_str = (char *) features_buf;
+  if (features_str[len - 1] != '\0')
+    {
+      features_str = xrealloc (features_str, len + 1);
+      features_str[len] = '\0';
+    }
+
+  if (baton->checksums)
+    add_xml_feature_to_cache (name, features_str);
+
+  return features_str;
+}
+
+/* Standard method to convert a string representation of available features
+   to a binary representation.  The string representation is fetched using
+   TARGET_OBJECT_AVAILABLE_FEATURES.  */
+
+/* TODO: Document \n conventions */
+
+struct gdb_feature_set *
+available_features_from_target_object (struct target_ops *ops,
+				       struct obstack *obstack)
+{
+  struct fetch_features_baton baton;
+  struct gdb_feature_set *features;
+  char *features_str, *checksums_str;
+  int ret;
+  struct xml_cache_entry *ent;
+  struct cleanup *back_to = make_cleanup (null_cleanup, NULL);
+
+  /* Reset the recently used flag so that we read any objects
+     without checksums from the target.  */
+  for (ent = xml_global_cache; ent != NULL; ent = ent->next)
+    ent->recently_used = 0;
+
+  /* Initialize the baton.  */
+  baton.ops = ops;
+  baton.checksums = NULL;
+
+  /* Attempt to read checksums from the target.  */
+  checksums_str = fetch_available_features_from_target ("CHECKSUMS", &baton);
+  if (checksums_str)
+    {
+      char *p;
+      int n_checksums;
+
+      make_cleanup (xfree, checksums_str);
+
+      /* Allow for one checksum in case there is no trailing newline,
+	 and one to serve as a NULL terminator.  */
+      n_checksums = 2;
+
+      /* Allocate one additional checksum per newline.  */
+      for (p = checksums_str; *p; p++)
+	if (*p == '\n')
+	  n_checksums++;
+
+      baton.checksums = xmalloc (n_checksums
+				 * sizeof (struct fetch_features_checksum));
+      make_cleanup (xfree, baton.checksums);
+
+      n_checksums = 0;
+      p = checksums_str;
+      while (*p)
+	{
+	  char *field_end;
+
+	  /* Find the first space on the line, marking the end of the
+	     checksum.  */
+	  field_end = p;
+	  while (*field_end && *field_end != '\n'
+		 && *field_end != ' ')
+	    field_end++;
+
+	  /* Check for a malformed checksum.  */
+	  if (*field_end != ' '
+	      || field_end - p != 40
+	      || checksum_to_bytes (p, baton.checksums[n_checksums].checksum))
+	    {
+	      /* Skip this line.  */
+	      p = field_end;
+	      while (*p && *p != '\n')
+		p++;
+	      if (*p == '\n')
+		p++;
+	      continue;
+	    }
+
+	  *field_end = '\0';
+
+	  /* Skip whitespace after the checksum.  */
+	  p = field_end + 1;
+	  while (*p == ' ')
+	    p++;
+
+	  field_end = p;
+	  while (*field_end && *field_end != '\n')
+	    field_end++;
+
+	  if (field_end == p)
+	    {
+	      /* Malformed line; skip it.  */
+	      if (*p == '\n')
+		p++;
+	      continue;
+	    }
+
+	  baton.checksums[n_checksums++].annex = p;
+
+	  /* Advance to the next line, inserting a NUL for the end of
+	     the annex name if necessary.  */
+	  if (*field_end)
+	    {
+	      *field_end = '\0';
+	      p = field_end + 1;
+	    }
+	  else
+	    break;
+	}
+
+      baton.checksums[n_checksums].annex = NULL;
+    }
+
+  /* FIXME: Memory management: what happens to features_str?  */
+
+  features_str = fetch_available_features_from_target ("target.xml", &baton);
+  if (features_str == NULL)
+    return NULL;
+
+  features = OBSTACK_ZALLOC (obstack, struct gdb_feature_set);
+  features->obstack = obstack;
+  ret = available_features_from_xml_string (features,
+					    features_str,
+					    fetch_available_features_from_target,
+					    &baton, 0);
+
+  do_cleanups (back_to);
+
+  if (ret < 0)
+    {
+      warning (_("Could not parse features XML from target"));
+      return NULL;
+    }
+
+  return features;
+}
+
+/* Return non-zero if LHS and RHS refer to compatible feature sets.  */
+
+int
+features_same_p (const struct gdb_feature_set *lhs,
+		 const struct gdb_feature_set *rhs)
+{
+  /* Two feature sets are the same if and only if they are described
+     by the same XML.  */
+
+  if (memcmp (lhs->checksum, rhs->checksum, 20) == 0)
+    return 1;
+  else
+    return 0;
+}
+
+/* Switch the architecture (gdbarch) to one which supports FEATURES.  */
+
+void
+arch_set_available_features (struct gdb_feature_set *features)
+{
+  volatile struct gdb_exception e;
+  struct gdbarch_info info;
+
+  TRY_CATCH (e, RETURN_MASK_ERROR)
+    {
+      gdbarch_info_init (&info);
+      info.feature_set = features;
+
+      if (!gdbarch_update_p (info))
+	internal_error (__FILE__, __LINE__, "could not update architecture");
+    }
+
+  if (e.reason == RETURN_ERROR)
+    exception_fprintf (gdb_stderr, e,
+		       _("warning: could not use supplied target description: "));
+}
+
+static struct gdb_feature_set *
+copy_features_to_obstack (struct obstack *obstack,
+			  const struct gdb_feature_set *features)
+{
+  struct gdb_feature_set *result;
+  struct gdb_available_feature **slot, *orig_feature;
+
+  result = obstack_alloc (obstack, sizeof (struct gdb_feature_set));
+  result->obstack = obstack;
+
+  slot = &result->features;
+  for (orig_feature = features->features;
+       orig_feature;
+       orig_feature = orig_feature->next)
+    {
+      struct gdb_available_feature *feature;
+      struct gdb_available_register **reg_slot, *orig_reg;
+
+      feature = OBSTACK_ZALLOC (obstack, struct gdb_available_feature);
+      *slot = feature;
+      slot = &feature->next;
+
+      memcpy (feature, orig_feature, sizeof (struct gdb_available_feature));
+      feature->name = obsavestring (feature->name, strlen (feature->name),
+				    obstack);
+      if (feature->arch_data)
+	feature->arch_data = obsavestring (feature->arch_data,
+					   strlen (feature->arch_data),
+					   obstack);
+
+      reg_slot = &feature->registers;
+      for (orig_reg = orig_feature->registers;
+	   orig_reg;
+	   orig_reg = orig_reg->next)
+	{
+	  struct gdb_available_register *reg;
+
+	  reg = OBSTACK_ZALLOC (obstack, struct gdb_available_register);
+	  *reg_slot = reg;
+	  reg_slot = &reg->next;
+
+	  memcpy (reg, orig_reg, sizeof (struct gdb_available_register));
+	  reg->name = obsavestring (reg->name, strlen (reg->name), obstack);
+	  if (reg->arch_data)
+	    reg->arch_data = obsavestring (reg->arch_data,
+					   strlen (reg->arch_data),
+					   obstack);
+	  if (reg->group)
+	    reg->group = obsavestring (reg->group, strlen (reg->group),
+				       obstack);
+	  if (reg->type)
+	    reg->type = obsavestring (reg->type, strlen (reg->type),
+				      obstack);
+	}
+    }
+
+  return result;
+}
+
+/* Set an architecture's feature set.  Store BASE_FEATURES in GDBARCH,
+   and on the correct obstack.
+
+   This function will update GDBARCH's num_regs.  It is the
+   architecture's responsibility to handle this if it has pseudo
+   registers.  Before calling this function, num_regs should be
+   the number of fixed registers handled by the target code; all
+   unassigned registers will be given numbers above that point.  */
+
+void
+record_available_features (struct gdbarch *gdbarch,
+			   struct gdb_feature_set *base_features)
+{
+  struct gdb_available_feature *feature;
+  struct gdb_available_register *reg;
+  struct gdb_feature_set *features;
+  int gdb_regnum;
+
+  features = copy_features_to_obstack (gdbarch_obstack (gdbarch),
+				       base_features);
+  set_gdbarch_feature_set (gdbarch, features);
+
+  gdb_regnum = gdbarch_num_regs (gdbarch);
+
+  for (feature = features->features; feature; feature = feature->next)
+    for (reg = feature->registers; reg; reg = reg->next)
+      if (reg->gdb_regnum == -1)
+	reg->gdb_regnum = gdb_regnum++;
+
+  set_gdbarch_num_regs (gdbarch, gdb_regnum);
+}
+
+/* Search FEATURES for a register with GDB register number REGNUM.  */
+
+static struct gdb_available_register *
+find_register (const struct gdb_feature_set *features, int regnum)
+{
+  struct gdb_available_feature *feature;
+  struct gdb_available_register *reg;
+
+  if (features == NULL)
+    return NULL;
+
+  for (feature = features->features; feature; feature = feature->next)
+    for (reg = feature->registers; reg; reg = reg->next)
+      if (reg->gdb_regnum == regnum)
+	return reg;
+
+  return NULL;
+}
+
+/* Search FEATURES for a register with target-specified name NAME, and
+   set its GDB register number to REGNUM.  Pass REGNUM == -1 if you do
+   not need to fix a register number for this register.  Return 1 if
+   the register was found, and 0 if it was not.  This function should
+   only be used while initializing a gdbarch.  */
+
+int
+available_find_named_register (struct gdb_feature_set *features,
+			       const char *name, int regnum)
+{
+  struct gdb_available_feature *feature;
+  struct gdb_available_register *reg;
+
+  if (features == NULL)
+    return 0;
+
+  for (feature = features->features; feature; feature = feature->next)
+    for (reg = feature->registers; reg; reg = reg->next)
+      if (strcmp (reg->name, name) == 0)
+	{
+	  reg->gdb_regnum = regnum;
+	  return 1;
+	}
+
+  /* FIXME: Should we sanity check the target-supplied data here for
+     duplicate register names?  Right now GDB can't handle duplicated
+     register names at all, but in the future it may.  */
+
+  return 0;
+}
+
+/* Search FEATURES for a feature with the well-known name NAME,
+   which GDB may have special support for.  */
+
+int
+available_find_named_feature (struct gdb_feature_set *features,
+			      const char *name)
+{
+  struct gdb_available_feature *feature;
+
+  if (features == NULL)
+    return 0;
+
+  for (feature = features->features; feature; feature = feature->next)
+    if (strcmp (feature->name, name) == 0)
+      return 1;
+
+  return 0;
+}
+
+/* Return the type of target-described register REGNUM, if the feature set
+   for GDBARCH describes that register.  Otherwise return NULL.  */
+
+struct type *
+available_register_type (struct gdbarch *gdbarch, int regnum)
+{
+  struct gdb_available_register *reg;
+
+  reg = find_register (gdbarch_feature_set (gdbarch), regnum);
+  if (reg == NULL)
+    return NULL;
+
+  if (reg->type && strcmp (reg->type, "float") == 0)
+    {
+      if (reg->bitsize == gdbarch_float_bit (gdbarch))
+	return builtin_type_float;
+      else if (reg->bitsize == gdbarch_double_bit (gdbarch))
+	return builtin_type_double;
+      else if (reg->bitsize == gdbarch_long_double_bit (gdbarch))
+	return builtin_type_long_double;
+    }
+
+  if (reg->type && strcmp (reg->type, "int") != 0)
+    {
+      /* FIXME: Warn the user about an unknown type + size?  */
+    }
+
+  /* Use an integer type; default to "long".  */
+  if (reg->bitsize == gdbarch_long_bit (gdbarch))
+    return builtin_type_long;
+  else if (reg->bitsize == TARGET_CHAR_BIT)
+    return builtin_type_signed_char;
+  else if (reg->bitsize == gdbarch_short_bit (gdbarch))
+    return builtin_type_short;
+  else if (reg->bitsize == gdbarch_int_bit (gdbarch))
+    return builtin_type_int;
+  else if (reg->bitsize == gdbarch_long_long_bit (gdbarch))
+    return builtin_type_long_long;
+  else if (reg->bitsize == gdbarch_ptr_bit (gdbarch))
+    /* A bit desperate by this point... */
+    return builtin_type_void_data_ptr;
+  else
+    {
+      /* FIXME: Create a new integer type of the appropriate size?  */
+      internal_error (__FILE__, __LINE__,
+		      _("GDB does not support %ld-bit registers on this target"),
+		      reg->bitsize);
+    }
+}
+
+/* Return the name of target-described register REGNUM, if the feature set
+   for GDBARCH describes that register.  Otherwise return NULL.  */
+
+const char *
+available_register_name (struct gdbarch *gdbarch, int regnum)
+{
+  struct gdb_available_register *reg;
+
+  reg = find_register (gdbarch_feature_set (gdbarch), regnum);
+  if (reg == NULL)
+    return NULL;
+
+  return reg->name;
+}
+
+/* Return the target-supplied register of target-described register
+   REGNUM, or -1 if the register can not be accessed.  */
+
+int
+available_register_target_regnum (struct gdbarch *gdbarch, int regnum)
+{
+  struct gdb_available_register *reg;
+
+  /* If there is no feature set, use the legacy 1:1 mapping.  */
+  if (gdbarch_feature_set (gdbarch) == NULL)
+    return regnum;
+
+  reg = find_register (gdbarch_feature_set (gdbarch), regnum);
+  if (reg == NULL)
+    return -1;
+
+  return reg->protocol_number;
+}
+
+/* Check whether REGNUM is a member of REGGROUP.  */
+
+/* TODO: This function only supports "info registers", "info float",
+   and "info vector".  Registers with group="general" go in general;
+   group="float" and group="vector" are similar.  Other specified
+   values of group go into all-registers only.  Registers with no
+   group specified go to the default function and are handled by
+   type.  When we have a hierarchy of features, it may make more
+   sense to use that to show registers.  */
+
+int
+available_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
+			       struct reggroup *reggroup)
+{
+  struct gdb_available_register *reg;
+
+  reg = find_register (gdbarch_feature_set (gdbarch), regnum);
+  if (reg != NULL && reg->group != NULL)
+    {
+      int general_p = 0, float_p = 0, vector_p = 0;
+
+      if (strcmp (reg->group, "general") == 0)
+	general_p = 1;
+      else if (strcmp (reg->group, "float") == 0)
+	float_p = 1;
+      else if (strcmp (reg->group, "vector") == 0)
+	vector_p = 1;
+
+      if (reggroup == float_reggroup)
+	return float_p;
+
+      if (reggroup == vector_reggroup)
+	return vector_p;
+
+      if (reggroup == general_reggroup)
+	return general_p;
+    }
+
+  if (reg != NULL
+      && (reggroup == save_reggroup || reggroup == restore_reggroup))
+    return reg->save_restore;
+
+  return default_register_reggroup_p (gdbarch, regnum, reggroup);
+}
diff --git a/gdb/available.h b/gdb/available.h
new file mode 100644
index 0000000..0008e5a
--- /dev/null
+++ b/gdb/available.h
@@ -0,0 +1,189 @@
+/* Support for runtime-defined target features for GDB.
+
+   Copyright (C) 2006
+   Free Software Foundation, Inc.
+
+   Contributed by CodeSourcery.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
+
+#ifndef AVAILABLE_H
+#define AVAILABLE_H 1
+
+struct obstack;
+struct reggroup;
+
+/* A GDB target interface can use these types to communicate to the
+   architecture support (gdbarch) what new or optional features
+   it supports.
+
+   Each individual gdb_available_feature describes a target-specific
+   unit of functionality, often including a group of registers,
+   possibly including other bits of which the debugger needs
+   explicit knowledge.  GDB may recognize the feature by name,
+   or query the target for additional details.  If it recognizes
+   the feature by name, it may take advantage of the feature's
+   presence in additional ways - e.g. by knowing the calling
+   conventions for functions using the new registers.
+
+   If GDB does not recognize the feature by name, and the feature
+   requests explicit debugger support, GDB may suggest an upgrade
+   to the user.  */
+
+struct gdb_feature_set
+{
+  struct gdb_available_feature *features;
+
+  struct obstack *obstack;
+
+  /* The checksum of the XML which generated this feature set.  */
+  /* FIXME: Should we just save the entire XML instead?  We're going
+     to need to have it around to show the frontend in the future.  */
+  unsigned char checksum[20];
+};
+
+struct gdb_available_feature
+{
+  /* The name of this feature.  For features, the name
+     is recognized by the architecture.  */
+  const char *name;
+
+  /* The protocol number used by this target to provide this feature.
+     For instance, the base register number for a group of raw
+     registers included in a known feature.  If none is necessary this
+     may be set to -1.  */
+  int protocol_number;
+
+  /* Data private to the architecture associated with this feature.
+     This is a NUL-terminated string.  */
+  const char *arch_data;
+
+  /* The registers associated with this feature.  */
+  struct gdb_available_register *registers;
+
+  /* Chain to the next available feature in this set.  */
+  struct gdb_available_feature *next;
+};
+
+struct gdb_available_register
+{
+  /* The name of this feature.  For registers, the name is
+     only used by the user interface.  */
+  const char *name;
+
+  /* The protocol number used by this target to provide this
+     feature.  For instance, the register number used for remote
+     p/P packets to access this register.  */
+  long protocol_number;
+
+  /* Data private to the architecture associated with this feature.
+     This is a NUL-terminated string.  */
+  const char *arch_data;
+
+  /* If this flag is set, GDB should save and restore this register
+     around calls to an inferior function.  */
+  int save_restore;
+
+  /* The name of the register group containing this register.  If this
+     is "general", "float", or "vector", the corresponding "info" command
+     should display this register's value.  It can be an arbitrary
+     string, but should be limited to alphanumeric characters and internal
+     hyphens.  */
+  const char *group;
+
+  /* The size of the register, in bits.  */
+  long bitsize;
+
+  /* The type of the register.  This is a target-supplied string,
+     corresponding to FIXME FIXME.  */
+  const char *type;
+
+  /* GDB internal state for this register; this may vary per copy
+     of this code in each gdbarch.  */
+
+  /* GDB register number for this register.  */
+  int gdb_regnum;
+
+  /* Chain to the next available register in this feature.  */
+  struct gdb_available_register *next;
+};
+
+/* Standard method to convert a string representation of available features
+   to a binary representation.  The string representation is fetched using
+   TARGET_OBJECT_AVAILABLE_FEATURES.  */
+
+struct gdb_feature_set *available_features_from_target_object
+  (struct target_ops *, struct obstack *);
+
+/* Standard method to update an architecture based on detected available
+   features.  */
+
+void arch_set_available_features (struct gdb_feature_set *);
+
+/* Compare two sets of available features.  */
+
+int features_same_p (const struct gdb_feature_set *,
+		     const struct gdb_feature_set *);
+
+/* Set an architecture's feature set.  */
+
+void record_available_features (struct gdbarch *,
+				struct gdb_feature_set *);
+
+/* Find a register with the given name, and optionally set its
+   internal register number.  */
+
+int available_find_named_register (struct gdb_feature_set *,
+				   const char *, int);
+
+/* Find a feature with the given name.  */
+
+int available_find_named_feature (struct gdb_feature_set *,
+				  const char *);
+
+/* Find the type of a target-described register.  */
+
+struct type *available_register_type (struct gdbarch *, int);
+
+/* Find the name of a target-described register.  */
+
+const char *available_register_name (struct gdbarch *, int);
+
+/* Find the target-supplied register number of a target-described register.  */
+
+int available_register_target_regnum (struct gdbarch *, int);
+
+/* Check the register group of a target-described register.  */
+
+int available_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
+				   struct reggroup *reggroup);
+
+/* Find a compiled-in XML file, e.g. the standard DTD.  */
+
+const char *fetch_xml_builtin (const char *);
+
+/* Internal routines shared by available.c and parse-avail.c.  */
+
+typedef char *(*xml_fetch_another) (const char *, void *);
+
+int available_features_from_xml_string (struct gdb_feature_set *,
+					const char *,
+					xml_fetch_another, void *,
+					int);
+
+#endif /* AVAILABLE_H */
diff --git a/gdb/avr-tdep.c b/gdb/avr-tdep.c
index 9c6566e..530caa6 100644
--- a/gdb/avr-tdep.c
+++ b/gdb/avr-tdep.c
@@ -1323,45 +1323,35 @@
 avr_io_reg_read_command (char *args, int from_tty)
 {
   LONGEST bufsiz = 0;
-  char buf[400];
+  gdb_byte *buf;
   char query[400];
   char *p;
   unsigned int nreg = 0;
   unsigned int val;
   int i, j, k, step;
 
-  /* Just get the maximum buffer size. */
-  bufsiz = target_read_partial (&current_target, TARGET_OBJECT_AVR,
-				NULL, NULL, 0, 0);
-  if (bufsiz < 0)
+  /* Find out how many io registers the target has. */
+  bufsiz = target_read_whole (&current_target, TARGET_OBJECT_AVR,
+			      "avr.io_reg", &buf);
+
+  if (bufsiz <= 0)
     {
       fprintf_unfiltered (gdb_stderr,
 			  _("ERR: info io_registers NOT supported "
 			    "by current target\n"));
       return;
     }
-  if (bufsiz > sizeof (buf))
-    bufsiz = sizeof (buf);
-
-  /* Find out how many io registers the target has. */
-  strcpy (query, "avr.io_reg");
-  target_read_partial (&current_target, TARGET_OBJECT_AVR, query, buf, 0,
-		       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"));
+      xfree (buf);
       return;
     }
 
+  xfree (buf);
+
   reinitialize_more_filter ();
 
   printf_unfiltered (_("Target has %u io registers:\n\n"), nreg);
@@ -1377,8 +1367,8 @@
         j = nreg - i;           /* last block is less than 8 registers */
 
       snprintf (query, sizeof (query) - 1, "avr.io_reg:%x,%x", i, j);
-      target_read_partial (&current_target, TARGET_OBJECT_AVR, query, buf,
-			   0, bufsiz);
+      bufsiz = target_read_whole (&current_target, TARGET_OBJECT_AVR, query,
+				  &buf);
 
       p = buf;
       for (k = i; k < (i + j); k++)
@@ -1393,6 +1383,8 @@
 		break;
 	    }
 	}
+
+      xfree (buf);
     }
 }
 
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index 31b3b4b..472d8d0 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -932,7 +932,7 @@
       /* FIXME drow/2003-09-09: It would be nice if evaluate_expression
 	 took a frame parameter, so that we didn't have to change the
 	 selected frame.  */
-      saved_frame_id = get_frame_id (deprecated_selected_frame);
+      saved_frame_id = get_frame_id (get_selected_frame (NULL));
 
       /* Determine if the watchpoint is within scope.  */
       if (bpt->owner->exp_valid_block == NULL)
@@ -5939,7 +5939,7 @@
 {
   struct symtabs_and_lines sals;
   struct symtab_and_line sal;
-  struct frame_info *prev_frame = get_prev_frame (deprecated_selected_frame);
+  struct frame_info *prev_frame = get_prev_frame (get_selected_frame (NULL));
   struct breakpoint *breakpoint;
   struct cleanup *old_chain;
   struct continuation_arg *arg1;
@@ -5976,7 +5976,7 @@
     /* Otherwise, specify the current frame, because we want to stop only
        at the very same frame.  */
     breakpoint = set_momentary_breakpoint (sal,
-					   get_frame_id (deprecated_selected_frame),
+					   get_frame_id (get_selected_frame (NULL)),
 					   bp_until);
 
   if (!target_can_async_p ())
diff --git a/gdb/cli/cli-cmds.c b/gdb/cli/cli-cmds.c
index 88b4956..2fc3445 100644
--- a/gdb/cli/cli-cmds.c
+++ b/gdb/cli/cli-cmds.c
@@ -862,10 +862,7 @@
   name = NULL;
   if (!arg)
     {
-      if (!deprecated_selected_frame)
-	error (_("No frame selected."));
-
-      pc = get_frame_pc (deprecated_selected_frame);
+      pc = get_frame_pc (get_selected_frame (_("No frame selected.")));
       if (find_pc_partial_function (pc, &name, &low, &high) == 0)
 	error (_("No function contains program counter for selected frame."));
 #if defined(TUI)
diff --git a/gdb/config.in b/gdb/config.in
index 12001e9..9dc0593 100644
--- a/gdb/config.in
+++ b/gdb/config.in
@@ -569,6 +569,21 @@
 /* Define to 1 if the `setpgrp' function takes no argument. */
 #undef SETPGRP_VOID
 
+/* The size of a `char', as computed by sizeof. */
+#undef SIZEOF_CHAR
+
+/* The size of a `int', as computed by sizeof. */
+#undef SIZEOF_INT
+
+/* The size of a `long', as computed by sizeof. */
+#undef SIZEOF_LONG
+
+/* The size of a `short', as computed by sizeof. */
+#undef SIZEOF_SHORT
+
+/* The size of a `void *', as computed by sizeof. */
+#undef SIZEOF_VOID_P
+
 /* 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.
@@ -600,6 +615,10 @@
 /* Define if the simulator is being linked in. */
 #undef WITH_SIM
 
+/* Define to 1 if your processor stores words with the most significant byte
+   first (like Motorola and SPARC, unlike Intel and VAX). */
+#undef WORDS_BIGENDIAN
+
 /* Define to 1 if on AIX 3.
    System headers sometimes define this.
    We just want to avoid a redefinition error message.  */
diff --git a/gdb/configure b/gdb/configure
index 869eb4b..1b66c93 100755
--- a/gdb/configure
+++ b/gdb/configure
@@ -2811,6 +2811,234 @@
 esac
 
 
+echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5
+echo $ECHO_N "checking whether byte ordering is bigendian... $ECHO_C" >&6
+if test "${ac_cv_c_bigendian+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  # See if sys/param.h defines the BYTE_ORDER macro.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <sys/param.h>
+
+int
+main ()
+{
+#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN
+ bogus endian macros
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  # It does; now see whether it defined to BIG_ENDIAN or not.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <sys/param.h>
+
+int
+main ()
+{
+#if BYTE_ORDER != BIG_ENDIAN
+ not big endian
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_c_bigendian=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_c_bigendian=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+# It does not; compile a test program.
+if test "$cross_compiling" = yes; then
+  # try to guess the endianness by grepping values into an object file
+  ac_cv_c_bigendian=unknown
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+short ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
+short ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
+void _ascii () { char *s = (char *) ascii_mm; s = (char *) ascii_ii; }
+short ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
+short ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
+void _ebcdic () { char *s = (char *) ebcdic_mm; s = (char *) ebcdic_ii; }
+int
+main ()
+{
+ _ascii (); _ebcdic ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  if grep BIGenDianSyS conftest.$ac_objext >/dev/null ; then
+  ac_cv_c_bigendian=yes
+fi
+if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then
+  if test "$ac_cv_c_bigendian" = unknown; then
+    ac_cv_c_bigendian=no
+  else
+    # finding both strings is unlikely to happen, but who knows?
+    ac_cv_c_bigendian=unknown
+  fi
+fi
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+int
+main ()
+{
+  /* Are we little or big endian?  From Harbison&Steele.  */
+  union
+  {
+    long l;
+    char c[sizeof (long)];
+  } u;
+  u.l = 1;
+  exit (u.c[sizeof (long) - 1] == 1);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_c_bigendian=no
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_c_bigendian=yes
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5
+echo "${ECHO_T}$ac_cv_c_bigendian" >&6
+case $ac_cv_c_bigendian in
+  yes)
+
+cat >>confdefs.h <<\_ACEOF
+#define WORDS_BIGENDIAN 1
+_ACEOF
+ ;;
+  no)
+     ;;
+  *)
+    { { echo "$as_me:$LINENO: error: unknown endianness
+presetting ac_cv_c_bigendian=no (or yes) will help" >&5
+echo "$as_me: error: unknown endianness
+presetting ac_cv_c_bigendian=no (or yes) will help" >&2;}
+   { (exit 1); exit 1; }; } ;;
+esac
+
+
 ac_aux_dir=
 for ac_dir in `cd $srcdir;pwd`/.. $srcdir/`cd $srcdir;pwd`/..; do
   if test -f $ac_dir/install-sh; then
@@ -12853,6 +13081,2756 @@
 done
 
 
+# Create a header we can use portably to get the standard integer types.
+
+
+inttype_headers=`echo inttypes.h sys/inttypes.h  | sed -e 's/,/ /g'`
+
+acx_cv_header_stdint=stddef.h
+acx_cv_header_stdint_kind="(already complete)"
+for i in stdint.h $inttype_headers; do
+  unset ac_cv_type_uintptr_t
+  unset ac_cv_type_uintmax_t
+  unset ac_cv_type_int_least32_t
+  unset ac_cv_type_int_fast32_t
+  unset ac_cv_type_uint64_t
+  echo $ECHO_N "looking for a compliant stdint.h in $i, $ECHO_C" >&6
+  echo "$as_me:$LINENO: checking for uintmax_t" >&5
+echo $ECHO_N "checking for uintmax_t... $ECHO_C" >&6
+if test "${ac_cv_type_uintmax_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <$i>
+
+int
+main ()
+{
+if ((uintmax_t *) 0)
+  return 0;
+if (sizeof (uintmax_t))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_uintmax_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_uintmax_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_uintmax_t" >&5
+echo "${ECHO_T}$ac_cv_type_uintmax_t" >&6
+if test $ac_cv_type_uintmax_t = yes; then
+  acx_cv_header_stdint=$i
+else
+  continue
+fi
+
+  echo "$as_me:$LINENO: checking for uintptr_t" >&5
+echo $ECHO_N "checking for uintptr_t... $ECHO_C" >&6
+if test "${ac_cv_type_uintptr_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <$i>
+
+int
+main ()
+{
+if ((uintptr_t *) 0)
+  return 0;
+if (sizeof (uintptr_t))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_uintptr_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_uintptr_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_uintptr_t" >&5
+echo "${ECHO_T}$ac_cv_type_uintptr_t" >&6
+if test $ac_cv_type_uintptr_t = yes; then
+  :
+else
+  acx_cv_header_stdint_kind="(mostly complete)"
+fi
+
+  echo "$as_me:$LINENO: checking for int_least32_t" >&5
+echo $ECHO_N "checking for int_least32_t... $ECHO_C" >&6
+if test "${ac_cv_type_int_least32_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <$i>
+
+int
+main ()
+{
+if ((int_least32_t *) 0)
+  return 0;
+if (sizeof (int_least32_t))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_int_least32_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_int_least32_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_int_least32_t" >&5
+echo "${ECHO_T}$ac_cv_type_int_least32_t" >&6
+if test $ac_cv_type_int_least32_t = yes; then
+  :
+else
+  acx_cv_header_stdint_kind="(mostly complete)"
+fi
+
+  echo "$as_me:$LINENO: checking for int_fast32_t" >&5
+echo $ECHO_N "checking for int_fast32_t... $ECHO_C" >&6
+if test "${ac_cv_type_int_fast32_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <$i>
+
+int
+main ()
+{
+if ((int_fast32_t *) 0)
+  return 0;
+if (sizeof (int_fast32_t))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_int_fast32_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_int_fast32_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_int_fast32_t" >&5
+echo "${ECHO_T}$ac_cv_type_int_fast32_t" >&6
+if test $ac_cv_type_int_fast32_t = yes; then
+  :
+else
+  acx_cv_header_stdint_kind="(mostly complete)"
+fi
+
+  echo "$as_me:$LINENO: checking for uint64_t" >&5
+echo $ECHO_N "checking for uint64_t... $ECHO_C" >&6
+if test "${ac_cv_type_uint64_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <$i>
+
+int
+main ()
+{
+if ((uint64_t *) 0)
+  return 0;
+if (sizeof (uint64_t))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_uint64_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_uint64_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_uint64_t" >&5
+echo "${ECHO_T}$ac_cv_type_uint64_t" >&6
+if test $ac_cv_type_uint64_t = yes; then
+  :
+else
+  acx_cv_header_stdint_kind="(lacks uint64_t)"
+fi
+
+  break
+done
+if test "$acx_cv_header_stdint" = stddef.h; then
+  acx_cv_header_stdint_kind="(lacks uintptr_t)"
+  for i in stdint.h $inttype_headers; do
+    unset ac_cv_type_uint32_t
+    unset ac_cv_type_uint64_t
+    echo $ECHO_N "looking for an incomplete stdint.h in $i, $ECHO_C" >&6
+    echo "$as_me:$LINENO: checking for uint32_t" >&5
+echo $ECHO_N "checking for uint32_t... $ECHO_C" >&6
+if test "${ac_cv_type_uint32_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <$i>
+
+int
+main ()
+{
+if ((uint32_t *) 0)
+  return 0;
+if (sizeof (uint32_t))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_uint32_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_uint32_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_uint32_t" >&5
+echo "${ECHO_T}$ac_cv_type_uint32_t" >&6
+if test $ac_cv_type_uint32_t = yes; then
+  acx_cv_header_stdint=$i
+else
+  continue
+fi
+
+    echo "$as_me:$LINENO: checking for uint64_t" >&5
+echo $ECHO_N "checking for uint64_t... $ECHO_C" >&6
+if test "${ac_cv_type_uint64_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <$i>
+
+int
+main ()
+{
+if ((uint64_t *) 0)
+  return 0;
+if (sizeof (uint64_t))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_uint64_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_uint64_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_uint64_t" >&5
+echo "${ECHO_T}$ac_cv_type_uint64_t" >&6
+if test $ac_cv_type_uint64_t = yes; then
+  :
+else
+  acx_cv_header_stdint_kind="(lacks uintptr_t and uint64_t)"
+fi
+
+    break
+  done
+fi
+if test "$acx_cv_header_stdint" = stddef.h; then
+  acx_cv_header_stdint_kind="(u_intXX_t style)"
+  for i in sys/types.h $inttype_headers; do
+    unset ac_cv_type_u_int32_t
+    unset ac_cv_type_u_int64_t
+    echo $ECHO_N "looking for u_intXX_t types in $i, $ECHO_C" >&6
+    echo "$as_me:$LINENO: checking for u_int32_t" >&5
+echo $ECHO_N "checking for u_int32_t... $ECHO_C" >&6
+if test "${ac_cv_type_u_int32_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <$i>
+
+int
+main ()
+{
+if ((u_int32_t *) 0)
+  return 0;
+if (sizeof (u_int32_t))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_u_int32_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_u_int32_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_u_int32_t" >&5
+echo "${ECHO_T}$ac_cv_type_u_int32_t" >&6
+if test $ac_cv_type_u_int32_t = yes; then
+  acx_cv_header_stdint=$i
+else
+  continue
+fi
+
+    echo "$as_me:$LINENO: checking for u_int64_t" >&5
+echo $ECHO_N "checking for u_int64_t... $ECHO_C" >&6
+if test "${ac_cv_type_u_int64_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <$i>
+
+int
+main ()
+{
+if ((u_int64_t *) 0)
+  return 0;
+if (sizeof (u_int64_t))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_u_int64_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_u_int64_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_u_int64_t" >&5
+echo "${ECHO_T}$ac_cv_type_u_int64_t" >&6
+if test $ac_cv_type_u_int64_t = yes; then
+  :
+else
+  acx_cv_header_stdint_kind="(u_intXX_t style, lacks u_int64_t)"
+fi
+
+    break
+  done
+fi
+if test "$acx_cv_header_stdint" = stddef.h; then
+  acx_cv_header_stdint_kind="(using manual detection)"
+fi
+
+test -z "$ac_cv_type_uintptr_t" && ac_cv_type_uintptr_t=no
+test -z "$ac_cv_type_uint64_t" && ac_cv_type_uint64_t=no
+test -z "$ac_cv_type_u_int64_t" && ac_cv_type_u_int64_t=no
+test -z "$ac_cv_type_int_least32_t" && ac_cv_type_int_least32_t=no
+test -z "$ac_cv_type_int_fast32_t" && ac_cv_type_int_fast32_t=no
+
+# ----------------- Summarize what we found so far
+
+echo "$as_me:$LINENO: checking what to include in gdb_stdint.h" >&5
+echo $ECHO_N "checking what to include in gdb_stdint.h... $ECHO_C" >&6
+
+case `$as_basename gdb_stdint.h ||
+$as_expr X/gdb_stdint.h : '.*/\([^/][^/]*\)/*$' \| \
+	 Xgdb_stdint.h : 'X\(//\)$' \| \
+	 Xgdb_stdint.h : 'X\(/\)$' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X/gdb_stdint.h |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+  	  /^X\/\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\/\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'` in
+  stdint.h) { echo "$as_me:$LINENO: WARNING: are you sure you want it there?" >&5
+echo "$as_me: WARNING: are you sure you want it there?" >&2;} ;;
+  inttypes.h) { echo "$as_me:$LINENO: WARNING: are you sure you want it there?" >&5
+echo "$as_me: WARNING: are you sure you want it there?" >&2;} ;;
+  *) ;;
+esac
+
+echo "$as_me:$LINENO: result: $acx_cv_header_stdint $acx_cv_header_stdint_kind" >&5
+echo "${ECHO_T}$acx_cv_header_stdint $acx_cv_header_stdint_kind" >&6
+
+# ----------------- done included file, check C basic types --------
+
+# Lacking an uintptr_t?  Test size of void *
+case "$acx_cv_header_stdint:$ac_cv_type_uintptr_t" in
+  stddef.h:* | *:no) echo "$as_me:$LINENO: checking for void *" >&5
+echo $ECHO_N "checking for void *... $ECHO_C" >&6
+if test "${ac_cv_type_void_p+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+if ((void * *) 0)
+  return 0;
+if (sizeof (void *))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_void_p=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_void_p=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_void_p" >&5
+echo "${ECHO_T}$ac_cv_type_void_p" >&6
+
+echo "$as_me:$LINENO: checking size of void *" >&5
+echo $ECHO_N "checking size of void *... $ECHO_C" >&6
+if test "${ac_cv_sizeof_void_p+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "$ac_cv_type_void_p" = yes; then
+  # The cast to unsigned long works around a bug in the HP C Compiler
+  # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+  # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+  # This bug is HP SR number 8606223364.
+  if test "$cross_compiling" = yes; then
+  # Depending upon the size, compute the lo and hi bounds.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (void *))) >= 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_lo=0 ac_mid=0
+  while :; do
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (void *))) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=$ac_mid; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr $ac_mid + 1`
+		    if test $ac_lo -le $ac_mid; then
+		      ac_lo= ac_hi=
+		      break
+		    fi
+		    ac_mid=`expr 2 '*' $ac_mid + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (void *))) < 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=-1 ac_mid=-1
+  while :; do
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (void *))) >= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_lo=$ac_mid; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_hi=`expr '(' $ac_mid ')' - 1`
+		       if test $ac_mid -le $ac_hi; then
+			 ac_lo= ac_hi=
+			 break
+		       fi
+		       ac_mid=`expr 2 '*' $ac_mid`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo= ac_hi=
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+  ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo`
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (void *))) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=$ac_mid
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr '(' $ac_mid ')' + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in
+?*) ac_cv_sizeof_void_p=$ac_lo;;
+'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (void *), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (void *), 77
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; } ;;
+esac
+else
+  if test "$cross_compiling" = yes; then
+  { { echo "$as_me:$LINENO: error: internal error: not reached in cross-compile" >&5
+echo "$as_me: error: internal error: not reached in cross-compile" >&2;}
+   { (exit 1); exit 1; }; }
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+long longval () { return (long) (sizeof (void *)); }
+unsigned long ulongval () { return (long) (sizeof (void *)); }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main ()
+{
+
+  FILE *f = fopen ("conftest.val", "w");
+  if (! f)
+    exit (1);
+  if (((long) (sizeof (void *))) < 0)
+    {
+      long i = longval ();
+      if (i != ((long) (sizeof (void *))))
+	exit (1);
+      fprintf (f, "%ld\n", i);
+    }
+  else
+    {
+      unsigned long i = ulongval ();
+      if (i != ((long) (sizeof (void *))))
+	exit (1);
+      fprintf (f, "%lu\n", i);
+    }
+  exit (ferror (f) || fclose (f) != 0);
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_sizeof_void_p=`cat conftest.val`
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+{ { echo "$as_me:$LINENO: error: cannot compute sizeof (void *), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (void *), 77
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+rm -f conftest.val
+else
+  ac_cv_sizeof_void_p=0
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sizeof_void_p" >&5
+echo "${ECHO_T}$ac_cv_sizeof_void_p" >&6
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_VOID_P $ac_cv_sizeof_void_p
+_ACEOF
+
+ ;;
+esac
+
+# Lacking an uint64_t?  Test size of long
+case "$acx_cv_header_stdint:$ac_cv_type_uint64_t:$ac_cv_type_u_int64_t" in
+  stddef.h:*:* | *:no:no) echo "$as_me:$LINENO: checking for long" >&5
+echo $ECHO_N "checking for long... $ECHO_C" >&6
+if test "${ac_cv_type_long+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+if ((long *) 0)
+  return 0;
+if (sizeof (long))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_long=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_long=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_long" >&5
+echo "${ECHO_T}$ac_cv_type_long" >&6
+
+echo "$as_me:$LINENO: checking size of long" >&5
+echo $ECHO_N "checking size of long... $ECHO_C" >&6
+if test "${ac_cv_sizeof_long+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "$ac_cv_type_long" = yes; then
+  # The cast to unsigned long works around a bug in the HP C Compiler
+  # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+  # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+  # This bug is HP SR number 8606223364.
+  if test "$cross_compiling" = yes; then
+  # Depending upon the size, compute the lo and hi bounds.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long))) >= 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_lo=0 ac_mid=0
+  while :; do
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long))) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=$ac_mid; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr $ac_mid + 1`
+		    if test $ac_lo -le $ac_mid; then
+		      ac_lo= ac_hi=
+		      break
+		    fi
+		    ac_mid=`expr 2 '*' $ac_mid + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long))) < 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=-1 ac_mid=-1
+  while :; do
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long))) >= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_lo=$ac_mid; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_hi=`expr '(' $ac_mid ')' - 1`
+		       if test $ac_mid -le $ac_hi; then
+			 ac_lo= ac_hi=
+			 break
+		       fi
+		       ac_mid=`expr 2 '*' $ac_mid`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo= ac_hi=
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+  ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo`
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long))) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=$ac_mid
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr '(' $ac_mid ')' + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in
+?*) ac_cv_sizeof_long=$ac_lo;;
+'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (long), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (long), 77
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; } ;;
+esac
+else
+  if test "$cross_compiling" = yes; then
+  { { echo "$as_me:$LINENO: error: internal error: not reached in cross-compile" >&5
+echo "$as_me: error: internal error: not reached in cross-compile" >&2;}
+   { (exit 1); exit 1; }; }
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+long longval () { return (long) (sizeof (long)); }
+unsigned long ulongval () { return (long) (sizeof (long)); }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main ()
+{
+
+  FILE *f = fopen ("conftest.val", "w");
+  if (! f)
+    exit (1);
+  if (((long) (sizeof (long))) < 0)
+    {
+      long i = longval ();
+      if (i != ((long) (sizeof (long))))
+	exit (1);
+      fprintf (f, "%ld\n", i);
+    }
+  else
+    {
+      unsigned long i = ulongval ();
+      if (i != ((long) (sizeof (long))))
+	exit (1);
+      fprintf (f, "%lu\n", i);
+    }
+  exit (ferror (f) || fclose (f) != 0);
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_sizeof_long=`cat conftest.val`
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+{ { echo "$as_me:$LINENO: error: cannot compute sizeof (long), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (long), 77
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+rm -f conftest.val
+else
+  ac_cv_sizeof_long=0
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sizeof_long" >&5
+echo "${ECHO_T}$ac_cv_sizeof_long" >&6
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_LONG $ac_cv_sizeof_long
+_ACEOF
+
+ ;;
+esac
+
+if test $acx_cv_header_stdint = stddef.h; then
+  # Lacking a good header?  Test size of everything and deduce all types.
+  echo "$as_me:$LINENO: checking for int" >&5
+echo $ECHO_N "checking for int... $ECHO_C" >&6
+if test "${ac_cv_type_int+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+if ((int *) 0)
+  return 0;
+if (sizeof (int))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_int=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_int=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_int" >&5
+echo "${ECHO_T}$ac_cv_type_int" >&6
+
+echo "$as_me:$LINENO: checking size of int" >&5
+echo $ECHO_N "checking size of int... $ECHO_C" >&6
+if test "${ac_cv_sizeof_int+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "$ac_cv_type_int" = yes; then
+  # The cast to unsigned long works around a bug in the HP C Compiler
+  # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+  # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+  # This bug is HP SR number 8606223364.
+  if test "$cross_compiling" = yes; then
+  # Depending upon the size, compute the lo and hi bounds.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (int))) >= 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_lo=0 ac_mid=0
+  while :; do
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (int))) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=$ac_mid; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr $ac_mid + 1`
+		    if test $ac_lo -le $ac_mid; then
+		      ac_lo= ac_hi=
+		      break
+		    fi
+		    ac_mid=`expr 2 '*' $ac_mid + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (int))) < 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=-1 ac_mid=-1
+  while :; do
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (int))) >= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_lo=$ac_mid; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_hi=`expr '(' $ac_mid ')' - 1`
+		       if test $ac_mid -le $ac_hi; then
+			 ac_lo= ac_hi=
+			 break
+		       fi
+		       ac_mid=`expr 2 '*' $ac_mid`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo= ac_hi=
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+  ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo`
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (int))) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=$ac_mid
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr '(' $ac_mid ')' + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in
+?*) ac_cv_sizeof_int=$ac_lo;;
+'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (int), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (int), 77
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; } ;;
+esac
+else
+  if test "$cross_compiling" = yes; then
+  { { echo "$as_me:$LINENO: error: internal error: not reached in cross-compile" >&5
+echo "$as_me: error: internal error: not reached in cross-compile" >&2;}
+   { (exit 1); exit 1; }; }
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+long longval () { return (long) (sizeof (int)); }
+unsigned long ulongval () { return (long) (sizeof (int)); }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main ()
+{
+
+  FILE *f = fopen ("conftest.val", "w");
+  if (! f)
+    exit (1);
+  if (((long) (sizeof (int))) < 0)
+    {
+      long i = longval ();
+      if (i != ((long) (sizeof (int))))
+	exit (1);
+      fprintf (f, "%ld\n", i);
+    }
+  else
+    {
+      unsigned long i = ulongval ();
+      if (i != ((long) (sizeof (int))))
+	exit (1);
+      fprintf (f, "%lu\n", i);
+    }
+  exit (ferror (f) || fclose (f) != 0);
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_sizeof_int=`cat conftest.val`
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+{ { echo "$as_me:$LINENO: error: cannot compute sizeof (int), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (int), 77
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+rm -f conftest.val
+else
+  ac_cv_sizeof_int=0
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sizeof_int" >&5
+echo "${ECHO_T}$ac_cv_sizeof_int" >&6
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_INT $ac_cv_sizeof_int
+_ACEOF
+
+
+  echo "$as_me:$LINENO: checking for short" >&5
+echo $ECHO_N "checking for short... $ECHO_C" >&6
+if test "${ac_cv_type_short+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+if ((short *) 0)
+  return 0;
+if (sizeof (short))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_short=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_short=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_short" >&5
+echo "${ECHO_T}$ac_cv_type_short" >&6
+
+echo "$as_me:$LINENO: checking size of short" >&5
+echo $ECHO_N "checking size of short... $ECHO_C" >&6
+if test "${ac_cv_sizeof_short+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "$ac_cv_type_short" = yes; then
+  # The cast to unsigned long works around a bug in the HP C Compiler
+  # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+  # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+  # This bug is HP SR number 8606223364.
+  if test "$cross_compiling" = yes; then
+  # Depending upon the size, compute the lo and hi bounds.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (short))) >= 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_lo=0 ac_mid=0
+  while :; do
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (short))) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=$ac_mid; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr $ac_mid + 1`
+		    if test $ac_lo -le $ac_mid; then
+		      ac_lo= ac_hi=
+		      break
+		    fi
+		    ac_mid=`expr 2 '*' $ac_mid + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (short))) < 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=-1 ac_mid=-1
+  while :; do
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (short))) >= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_lo=$ac_mid; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_hi=`expr '(' $ac_mid ')' - 1`
+		       if test $ac_mid -le $ac_hi; then
+			 ac_lo= ac_hi=
+			 break
+		       fi
+		       ac_mid=`expr 2 '*' $ac_mid`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo= ac_hi=
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+  ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo`
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (short))) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=$ac_mid
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr '(' $ac_mid ')' + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in
+?*) ac_cv_sizeof_short=$ac_lo;;
+'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (short), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (short), 77
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; } ;;
+esac
+else
+  if test "$cross_compiling" = yes; then
+  { { echo "$as_me:$LINENO: error: internal error: not reached in cross-compile" >&5
+echo "$as_me: error: internal error: not reached in cross-compile" >&2;}
+   { (exit 1); exit 1; }; }
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+long longval () { return (long) (sizeof (short)); }
+unsigned long ulongval () { return (long) (sizeof (short)); }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main ()
+{
+
+  FILE *f = fopen ("conftest.val", "w");
+  if (! f)
+    exit (1);
+  if (((long) (sizeof (short))) < 0)
+    {
+      long i = longval ();
+      if (i != ((long) (sizeof (short))))
+	exit (1);
+      fprintf (f, "%ld\n", i);
+    }
+  else
+    {
+      unsigned long i = ulongval ();
+      if (i != ((long) (sizeof (short))))
+	exit (1);
+      fprintf (f, "%lu\n", i);
+    }
+  exit (ferror (f) || fclose (f) != 0);
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_sizeof_short=`cat conftest.val`
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+{ { echo "$as_me:$LINENO: error: cannot compute sizeof (short), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (short), 77
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+rm -f conftest.val
+else
+  ac_cv_sizeof_short=0
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sizeof_short" >&5
+echo "${ECHO_T}$ac_cv_sizeof_short" >&6
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_SHORT $ac_cv_sizeof_short
+_ACEOF
+
+
+  echo "$as_me:$LINENO: checking for char" >&5
+echo $ECHO_N "checking for char... $ECHO_C" >&6
+if test "${ac_cv_type_char+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+if ((char *) 0)
+  return 0;
+if (sizeof (char))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_char=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_char=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_char" >&5
+echo "${ECHO_T}$ac_cv_type_char" >&6
+
+echo "$as_me:$LINENO: checking size of char" >&5
+echo $ECHO_N "checking size of char... $ECHO_C" >&6
+if test "${ac_cv_sizeof_char+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "$ac_cv_type_char" = yes; then
+  # The cast to unsigned long works around a bug in the HP C Compiler
+  # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+  # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+  # This bug is HP SR number 8606223364.
+  if test "$cross_compiling" = yes; then
+  # Depending upon the size, compute the lo and hi bounds.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (char))) >= 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_lo=0 ac_mid=0
+  while :; do
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (char))) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=$ac_mid; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr $ac_mid + 1`
+		    if test $ac_lo -le $ac_mid; then
+		      ac_lo= ac_hi=
+		      break
+		    fi
+		    ac_mid=`expr 2 '*' $ac_mid + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (char))) < 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=-1 ac_mid=-1
+  while :; do
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (char))) >= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_lo=$ac_mid; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_hi=`expr '(' $ac_mid ')' - 1`
+		       if test $ac_mid -le $ac_hi; then
+			 ac_lo= ac_hi=
+			 break
+		       fi
+		       ac_mid=`expr 2 '*' $ac_mid`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo= ac_hi=
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+  ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo`
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (char))) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=$ac_mid
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr '(' $ac_mid ')' + 1`
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in
+?*) ac_cv_sizeof_char=$ac_lo;;
+'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (char), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (char), 77
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; } ;;
+esac
+else
+  if test "$cross_compiling" = yes; then
+  { { echo "$as_me:$LINENO: error: internal error: not reached in cross-compile" >&5
+echo "$as_me: error: internal error: not reached in cross-compile" >&2;}
+   { (exit 1); exit 1; }; }
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+long longval () { return (long) (sizeof (char)); }
+unsigned long ulongval () { return (long) (sizeof (char)); }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main ()
+{
+
+  FILE *f = fopen ("conftest.val", "w");
+  if (! f)
+    exit (1);
+  if (((long) (sizeof (char))) < 0)
+    {
+      long i = longval ();
+      if (i != ((long) (sizeof (char))))
+	exit (1);
+      fprintf (f, "%ld\n", i);
+    }
+  else
+    {
+      unsigned long i = ulongval ();
+      if (i != ((long) (sizeof (char))))
+	exit (1);
+      fprintf (f, "%lu\n", i);
+    }
+  exit (ferror (f) || fclose (f) != 0);
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_sizeof_char=`cat conftest.val`
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+{ { echo "$as_me:$LINENO: error: cannot compute sizeof (char), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (char), 77
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+rm -f conftest.val
+else
+  ac_cv_sizeof_char=0
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sizeof_char" >&5
+echo "${ECHO_T}$ac_cv_sizeof_char" >&6
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_CHAR $ac_cv_sizeof_char
+_ACEOF
+
+
+
+  echo "$as_me:$LINENO: checking for type equivalent to int8_t" >&5
+echo $ECHO_N "checking for type equivalent to int8_t... $ECHO_C" >&6
+  case "$ac_cv_sizeof_char" in
+    1) acx_cv_type_int8_t=char ;;
+    *) { { echo "$as_me:$LINENO: error: no 8-bit type" >&5
+echo "$as_me: error: no 8-bit type" >&2;}
+   { (exit please report a bug); exit please report a bug; }; }
+  esac
+  echo "$as_me:$LINENO: result: $acx_cv_type_int8_t" >&5
+echo "${ECHO_T}$acx_cv_type_int8_t" >&6
+
+  echo "$as_me:$LINENO: checking for type equivalent to int16_t" >&5
+echo $ECHO_N "checking for type equivalent to int16_t... $ECHO_C" >&6
+  case "$ac_cv_sizeof_int:$ac_cv_sizeof_short" in
+    2:*) acx_cv_type_int16_t=int ;;
+    *:2) acx_cv_type_int16_t=short ;;
+    *) { { echo "$as_me:$LINENO: error: no 16-bit type" >&5
+echo "$as_me: error: no 16-bit type" >&2;}
+   { (exit please report a bug); exit please report a bug; }; }
+  esac
+  echo "$as_me:$LINENO: result: $acx_cv_type_int16_t" >&5
+echo "${ECHO_T}$acx_cv_type_int16_t" >&6
+
+  echo "$as_me:$LINENO: checking for type equivalent to int32_t" >&5
+echo $ECHO_N "checking for type equivalent to int32_t... $ECHO_C" >&6
+  case "$ac_cv_sizeof_int:$ac_cv_sizeof_long" in
+    4:*) acx_cv_type_int32_t=int ;;
+    *:4) acx_cv_type_int32_t=long ;;
+    *) { { echo "$as_me:$LINENO: error: no 32-bit type" >&5
+echo "$as_me: error: no 32-bit type" >&2;}
+   { (exit please report a bug); exit please report a bug; }; }
+  esac
+  echo "$as_me:$LINENO: result: $acx_cv_type_int32_t" >&5
+echo "${ECHO_T}$acx_cv_type_int32_t" >&6
+fi
+
+# These tests are here to make the output prettier
+
+if test "$ac_cv_type_uint64_t" != yes && test "$ac_cv_type_u_int64_t" != yes; then
+  case "$ac_cv_sizeof_long" in
+    8) acx_cv_type_int64_t=long ;;
+  esac
+  echo "$as_me:$LINENO: checking for type equivalent to int64_t" >&5
+echo $ECHO_N "checking for type equivalent to int64_t... $ECHO_C" >&6
+  echo "$as_me:$LINENO: result: ${acx_cv_type_int64_t-'using preprocessor symbols'}" >&5
+echo "${ECHO_T}${acx_cv_type_int64_t-'using preprocessor symbols'}" >&6
+fi
+
+# Now we can use the above types
+
+if test "$ac_cv_type_uintptr_t" != yes; then
+  echo "$as_me:$LINENO: checking for type equivalent to intptr_t" >&5
+echo $ECHO_N "checking for type equivalent to intptr_t... $ECHO_C" >&6
+  case $ac_cv_sizeof_void_p in
+    2) acx_cv_type_intptr_t=int16_t ;;
+    4) acx_cv_type_intptr_t=int32_t ;;
+    8) acx_cv_type_intptr_t=int64_t ;;
+    *) { { echo "$as_me:$LINENO: error: no equivalent for intptr_t" >&5
+echo "$as_me: error: no equivalent for intptr_t" >&2;}
+   { (exit please report a bug); exit please report a bug; }; }
+  esac
+  echo "$as_me:$LINENO: result: $acx_cv_type_intptr_t" >&5
+echo "${ECHO_T}$acx_cv_type_intptr_t" >&6
+fi
+
+# ----------------- done all checks, emit header -------------
+          ac_config_commands="$ac_config_commands gdb_stdint.h"
+
+
+
+
 # ------------------------- #
 # Checks for declarations.  #
 # ------------------------- #
@@ -22479,6 +25457,24 @@
 #
 
 
+GCC="$GCC"
+CC="$CC"
+acx_cv_header_stdint="$acx_cv_header_stdint"
+acx_cv_type_int8_t="$acx_cv_type_int8_t"
+acx_cv_type_int16_t="$acx_cv_type_int16_t"
+acx_cv_type_int32_t="$acx_cv_type_int32_t"
+acx_cv_type_int64_t="$acx_cv_type_int64_t"
+acx_cv_type_intptr_t="$acx_cv_type_intptr_t"
+ac_cv_type_uintmax_t="$ac_cv_type_uintmax_t"
+ac_cv_type_uintptr_t="$ac_cv_type_uintptr_t"
+ac_cv_type_uint64_t="$ac_cv_type_uint64_t"
+ac_cv_type_u_int64_t="$ac_cv_type_u_int64_t"
+ac_cv_type_u_int32_t="$ac_cv_type_u_int32_t"
+ac_cv_type_int_least32_t="$ac_cv_type_int_least32_t"
+ac_cv_type_int_fast32_t="$ac_cv_type_int_fast32_t"
+ac_cv_sizeof_void_p="$ac_cv_sizeof_void_p"
+
+
 gdb_host_cpu=$gdb_host_cpu
 gdb_target_cpu=$gdb_target_cpu
 nativefile=$nativefile
@@ -22496,6 +25492,7 @@
   "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
   ".gdbinit" ) CONFIG_FILES="$CONFIG_FILES .gdbinit:gdbinit.in" ;;
   "$ac_config_links_1" ) CONFIG_LINKS="$CONFIG_LINKS $ac_config_links_1" ;;
+  "gdb_stdint.h" ) CONFIG_COMMANDS="$CONFIG_COMMANDS gdb_stdint.h" ;;
   "default" ) CONFIG_COMMANDS="$CONFIG_COMMANDS default" ;;
   "config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS config.h:config.in" ;;
   *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
@@ -23447,6 +26444,295 @@
   { echo "$as_me:$LINENO: executing $ac_dest commands" >&5
 echo "$as_me: executing $ac_dest commands" >&6;}
   case $ac_dest in
+    gdb_stdint.h )
+if test "$GCC" = yes; then
+  echo "/* generated for " `$CC --version | sed 1q` "*/" > tmp-stdint.h
+else
+  echo "/* generated for $CC */" > tmp-stdint.h
+fi
+
+sed 's/^ *//' >> tmp-stdint.h <<EOF
+
+  #ifndef GCC_GENERATED_STDINT_H
+  #define GCC_GENERATED_STDINT_H 1
+
+  #include <sys/types.h>
+EOF
+
+if test "$acx_cv_header_stdint" != stdint.h; then
+  echo "#include <stddef.h>" >> tmp-stdint.h
+fi
+if test "$acx_cv_header_stdint" != stddef.h; then
+  echo "#include <$acx_cv_header_stdint>" >> tmp-stdint.h
+fi
+
+sed 's/^ *//' >> tmp-stdint.h <<EOF
+  /* glibc uses these symbols as guards to prevent redefinitions.  */
+  #ifdef __int8_t_defined
+  #define _INT8_T
+  #define _INT16_T
+  #define _INT32_T
+  #endif
+  #ifdef __uint32_t_defined
+  #define _UINT32_T
+  #endif
+
+EOF
+
+# ----------------- done header, emit basic int types -------------
+if test "$acx_cv_header_stdint" = stddef.h; then
+  sed 's/^ *//' >> tmp-stdint.h <<EOF
+
+    #ifndef _UINT8_T
+    #define _UINT8_T
+    typedef unsigned $acx_cv_type_int8_t uint8_t;
+    #endif
+
+    #ifndef _UINT16_T
+    #define _UINT16_T
+    typedef unsigned $acx_cv_type_int16_t uint16_t;
+    #endif
+
+    #ifndef _UINT32_T
+    #define _UINT32_T
+    typedef unsigned $acx_cv_type_int32_t uint32_t;
+    #endif
+
+    #ifndef _INT8_T
+    #define _INT8_T
+    typedef $acx_cv_type_int8_t int8_t;
+    #endif
+
+    #ifndef _INT16_T
+    #define _INT16_T
+    typedef $acx_cv_type_int16_t int16_t;
+    #endif
+
+    #ifndef _INT32_T
+    #define _INT32_T
+    typedef $acx_cv_type_int32_t int32_t;
+    #endif
+EOF
+elif test "$ac_cv_type_u_int32_t" = yes; then
+  sed 's/^ *//' >> tmp-stdint.h <<EOF
+
+    /* int8_t int16_t int32_t defined by inet code, we do the u_intXX types */
+    #ifndef _INT8_T
+    #define _INT8_T
+    #endif
+    #ifndef _INT16_T
+    #define _INT16_T
+    #endif
+    #ifndef _INT32_T
+    #define _INT32_T
+    #endif
+
+    #ifndef _UINT8_T
+    #define _UINT8_T
+    typedef u_int8_t uint8_t;
+    #endif
+
+    #ifndef _UINT16_T
+    #define _UINT16_T
+    typedef u_int16_t uint16_t;
+    #endif
+
+    #ifndef _UINT32_T
+    #define _UINT32_T
+    typedef u_int32_t uint32_t;
+    #endif
+EOF
+else
+  sed 's/^ *//' >> tmp-stdint.h <<EOF
+
+    /* Some systems have guard macros to prevent redefinitions, define them.  */
+    #ifndef _INT8_T
+    #define _INT8_T
+    #endif
+    #ifndef _INT16_T
+    #define _INT16_T
+    #endif
+    #ifndef _INT32_T
+    #define _INT32_T
+    #endif
+    #ifndef _UINT8_T
+    #define _UINT8_T
+    #endif
+    #ifndef _UINT16_T
+    #define _UINT16_T
+    #endif
+    #ifndef _UINT32_T
+    #define _UINT32_T
+    #endif
+EOF
+fi
+
+# ------------- done basic int types, emit int64_t types ------------
+if test "$ac_cv_type_uint64_t" = yes; then
+  sed 's/^ *//' >> tmp-stdint.h <<EOF
+
+    /* system headers have good uint64_t and int64_t */
+    #ifndef _INT64_T
+    #define _INT64_T
+    #endif
+    #ifndef _UINT64_T
+    #define _UINT64_T
+    #endif
+EOF
+elif test "$ac_cv_type_u_int64_t" = yes; then
+  sed 's/^ *//' >> tmp-stdint.h <<EOF
+
+    /* system headers have an u_int64_t (and int64_t) */
+    #ifndef _INT64_T
+    #define _INT64_T
+    #endif
+    #ifndef _UINT64_T
+    #define _UINT64_T
+    typedef u_int64_t uint64_t;
+    #endif
+EOF
+elif test -n "$acx_cv_type_int64_t"; then
+  sed 's/^ *//' >> tmp-stdint.h <<EOF
+
+    /* architecture has a 64-bit type, $acx_cv_type_int64_t */
+    #ifndef _INT64_T
+    #define _INT64_T
+    typedef $acx_cv_type_int64_t int64_t;
+    #endif
+    #ifndef _UINT64_T
+    #define _UINT64_T
+    typedef unsigned $acx_cv_type_int64_t uint64_t;
+    #endif
+EOF
+else
+  sed 's/^ *//' >> tmp-stdint.h <<EOF
+
+    /* some common heuristics for int64_t, using compiler-specific tests */
+    #if defined __STDC_VERSION__ && (__STDC_VERSION__-0) >= 199901L
+    #ifndef _INT64_T
+    #define _INT64_T
+    typedef long long int64_t;
+    #endif
+    #ifndef _UINT64_T
+    #define _UINT64_T
+    typedef unsigned long long uint64_t;
+    #endif
+
+    #elif defined __GNUC__ && defined (__STDC__) && __STDC__-0
+    /* NextStep 2.0 cc is really gcc 1.93 but it defines __GNUC__ = 2 and
+       does not implement __extension__.  But that compiler doesn't define
+       __GNUC_MINOR__.  */
+    # if __GNUC__ < 2 || (__NeXT__ && !__GNUC_MINOR__)
+    # define __extension__
+    # endif
+
+    # ifndef _INT64_T
+    # define _INT64_T
+    __extension__ typedef long long int64_t;
+    # endif
+    # ifndef _UINT64_T
+    # define _UINT64_T
+    __extension__ typedef unsigned long long uint64_t;
+    # endif
+
+    #elif !defined __STRICT_ANSI__
+    # if defined _MSC_VER || defined __WATCOMC__ || defined __BORLANDC__
+
+    #  ifndef _INT64_T
+    #  define _INT64_T
+    typedef __int64 int64_t;
+    #  endif
+    #  ifndef _UINT64_T
+    #  define _UINT64_T
+    typedef unsigned __int64 uint64_t;
+    #  endif
+    # endif /* compiler */
+
+    #endif /* ANSI version */
+EOF
+fi
+
+# ------------- done int64_t types, emit intptr types ------------
+if test "$ac_cv_type_uintptr_t" != yes; then
+  sed 's/^ *//' >> tmp-stdint.h <<EOF
+
+    /* Define intptr_t based on sizeof(void*) = $ac_cv_sizeof_void_p */
+    typedef u$acx_cv_type_intptr_t uintptr_t;
+    typedef $acx_cv_type_intptr_t  intptr_t;
+EOF
+fi
+
+# ------------- done intptr types, emit int_least types ------------
+if test "$ac_cv_type_int_least32_t" != yes; then
+  sed 's/^ *//' >> tmp-stdint.h <<EOF
+
+    /* Define int_least types */
+    typedef int8_t     int_least8_t;
+    typedef int16_t    int_least16_t;
+    typedef int32_t    int_least32_t;
+    #ifdef _INT64_T
+    typedef int64_t    int_least64_t;
+    #endif
+
+    typedef uint8_t    uint_least8_t;
+    typedef uint16_t   uint_least16_t;
+    typedef uint32_t   uint_least32_t;
+    #ifdef _UINT64_T
+    typedef uint64_t   uint_least64_t;
+    #endif
+EOF
+fi
+
+# ------------- done intptr types, emit int_fast types ------------
+if test "$ac_cv_type_int_fast32_t" != yes; then
+      sed 's/^ *//' >> tmp-stdint.h <<EOF
+
+    /* Define int_fast types.  short is often slow */
+    typedef int8_t       int_fast8_t;
+    typedef int          int_fast16_t;
+    typedef int32_t      int_fast32_t;
+    #ifdef _INT64_T
+    typedef int64_t      int_fast64_t;
+    #endif
+
+    typedef uint8_t      uint_fast8_t;
+    typedef unsigned int uint_fast16_t;
+    typedef uint32_t     uint_fast32_t;
+    #ifdef _UINT64_T
+    typedef uint64_t     uint_fast64_t;
+    #endif
+EOF
+fi
+
+if test "$ac_cv_type_uintmax_t" != yes; then
+  sed 's/^ *//' >> tmp-stdint.h <<EOF
+
+    /* Define intmax based on what we found */
+    #ifdef _INT64_T
+    typedef int64_t       intmax_t;
+    #else
+    typedef long          intmax_t;
+    #endif
+    #ifdef _UINT64_T
+    typedef uint64_t      uintmax_t;
+    #else
+    typedef unsigned long uintmax_t;
+    #endif
+EOF
+fi
+
+sed 's/^ *//' >> tmp-stdint.h <<EOF
+
+  #endif /* GCC_GENERATED_STDINT_H */
+EOF
+
+if test -r gdb_stdint.h && cmp -s tmp-stdint.h gdb_stdint.h; then
+  rm -f tmp-stdint.h
+else
+  mv -f tmp-stdint.h gdb_stdint.h
+fi
+
+ ;;
     default )
 
 sed -e '/^DEPRECATED_TM_FILE[ 	]*=/s,^DEPRECATED_TM_FILE[ 	]*=[ 	]*,&config/'"${gdb_target_cpu}"'/,
diff --git a/gdb/configure.ac b/gdb/configure.ac
index 2725e18..906aa70 100644
--- a/gdb/configure.ac
+++ b/gdb/configure.ac
@@ -33,6 +33,9 @@
 AC_ISC_POSIX
 AM_PROG_CC_STDC
 
+dnl The SHA-1 implementation needs to know the host endianness.
+AC_C_BIGENDIAN
+
 AC_CONFIG_AUX_DIR(`cd $srcdir;pwd`/..)
 AC_CANONICAL_SYSTEM
 
@@ -422,6 +425,9 @@
 # unconditionally, so what's the point in checking these?
 AC_CHECK_HEADERS(ctype.h time.h)
 
+# Create a header we can use portably to get the standard integer types.
+GCC_HEADER_STDINT(gdb_stdint.h)
+
 # ------------------------- #
 # Checks for declarations.  #
 # ------------------------- #
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index ca8d80f..d79933a 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -159,6 +159,8 @@
 * Maintenance Commands::        Maintenance Commands
 * Remote Protocol::             GDB Remote Serial Protocol
 * Agent Expressions::           The GDB Agent Expression Mechanism
+* Self-Describing Targets::     How targets can describe themselves to
+                                @value{GDBN}
 * Copying::			GNU General Public License says
                                 how you can copy and share GDB
 * GNU Free Documentation License::  The license for this documentation
@@ -23250,6 +23252,7 @@
 @item qPart:@var{object}:read:@var{annex}:@var{offset},@var{length}
 @cindex read special object, remote request
 @cindex @samp{qPart} packet
+@anchor{the qPart request}
 Read uninterpreted bytes from the target's special data area
 identified by the keyword @var{object}.  Request @var{length} bytes
 starting at @var{offset} bytes into the data.  The content and
@@ -23261,10 +23264,16 @@
 formats, listed below.
 
 @table @samp
+
 @item qPart:auxv:read::@var{offset},@var{length}
 Access the target's @dfn{auxiliary vector}.  @xref{OS Information,
 auxiliary vector}, and see @ref{Remote configuration,
 read-aux-vector-packet}.  Note @var{annex} must be empty.
+
+@item qPart:features:read:@var{annex}:@var{offset},@var{length}
+Retrieve information describing features the target supports (register
+sets, memory regions, and so on).  @xref{Self-Describing Targets}.
+
 @end table
 
 Reply:
@@ -24809,6 +24818,258 @@
 
 @include agentexpr.texi
 
+@node Self-Describing Targets
+@appendix Self-Describing Targets
+
+One of the challenges of using @value{GDBN} to debug embedded systems
+is that there are so many minor variants of each processor
+architecture in use.  It is common practice for vendors to start with
+a standard processor core --- ARM, PowerPC, or MIPS, for example ---
+and then make changes to adapt it to a particular market niche.  Some
+architectures have hundreds of variants, available from dozens of
+vendors.  This leads to a number of problems:
+
+@itemize @bullet
+@item
+With so many different customized processors, it is difficult for
+the @value{GDBN} maintainers to keep up with the changes.
+@item
+Since individual variants may have short lifetimes or limited
+audiences, it may not be worthwhile to carry information about every
+variant in the @value{GDBN} source tree.
+@item
+When @value{GDBN} does support the architecture of the embedded system
+at hand, the task of finding the correct architecture name to give the
+@command{set architecture} command can be error-prone.
+@end itemize
+
+To address these problems, the @value{GDBN} remote protocol allows a
+target system to not only identify itself to @value{GDBN}, but to
+actually describe its own features.  This lets @value{GDBN} support
+processor variants it has never seen before --- to the extent that the
+descriptions are accurate, and that @value{GDBN} understands them.
+
+@menu
+* Retrieving Self-Descriptions::    How descriptions are fetched from a target.
+* Self-Description Format::         The contents of a self-description.
+@end menu
+
+@node Retrieving Self-Descriptions
+@section Retrieving Self-Descriptions
+
+A target can split its self-description into one or more pieces,
+called @dfn{annexes}.  @value{GDBN} retrieves each annex via the
+remote protocol using @code{qPart} requests (@pxref{the qPart
+request}) of the form:
+
+@example
+qPart:features:read:@var{annex}:@var{offset},@var{length}
+@end example
+
+@noindent
+where @var{annex} is the name of the annex, and the @var{offset} and
+@var{length} parameters are the offset into the description and the
+number of bytes to transfer, as for other @code{qPart} requests.
+
+To retrieve a target's self-description, @value{GDBN} first fetches
+the annex named @samp{target.xml}.  This is an XML document, of the
+form described in @ref{Self-Description Format}.  Just as C header
+files can refer to other header files using @code{#include}, target
+description annexes can use @uref{http://www.w3.org/TR/xinclude/, XML
+Inclusions} to incorporate other annexes.  Starting with
+@samp{target.xml}, @value{GDBN} makes further @code{qPart} requests as
+needed to resolve all the inclusions and assemble the complete
+description.
+
+To reduce protocol overhead, a target may supply a special annex named
+@samp{CHECKSUMS} that provides 160-bit SHA-1@footnote{The SHA-1 hash
+function is defined in
+@uref{http://www.itl.nist.gov/fipspubs/fip180-1.htm, Federal
+Information Processing Standards Publication 180-1}.  The GNU
+coreutils contain a Free implementation of SHA-1.}  checksum values
+for the annexes it has available.  The @samp{CHECKSUMS} annex contains
+a series of newline-terminated lines, each of which contains a
+40-digit hexidecimal checksum, two spaces, and the name of an annex
+with the given checksum.  Here is an example @samp{CHECKSUMS} annex:
+
+@example
+68c94ffc34f8ad2d7bfae3f5a6b996409211c1b1  target.xml
+0e8e850b0580fbaaa0872326cb1b8ad6adda9b0d  mmu.xml
+00f22e5f971ccec05c2acce98caf8cff4343c8cf  fpu.xml
+@end example
+
+@value{GDBN} uses these checksums to avoid retrieving a given annex
+more than once.  When @value{GDBN} retrieves an annex, it caches its
+contents locally.  Then, each time @value{GDBN} thinks the target
+architecture may have changed (say, after making a new remote protocol
+connection, or after starting a new child process using the extended
+remote protocol), it retrieves the @samp{CHECKSUMS} annex afresh.  If
+the checksums show that a particular annex's contents are the same on
+the target and in @value{GDBN}'s cache, @value{GDBN} avoids fetching
+it again.  If none of the annexes have changed, @value{GDBN} needs
+only retrieve the @samp{CHECKSUMS} annex.
+
+@samp{CHECKSUMS} need not provide a checksum for every annex
+available; if a given annex is not mentioned, @value{GDBN} will try to
+retrieve it each time it thinks the target architecture may have
+changed.  The target need not provide any @samp{CHECKSUMS} annex at
+all; this is equivalent to an empty @samp{CHECKSUMS} annex.
+
+
+@node Self-Description Format
+@section Self-Description Format
+
+A target description annex is an @uref{http://www.w3.org/XML/, XML}
+document which complies with the Document Type Definition provided in
+the @value{GDBN} sources in @file{gdb/features/gdb-target.dtd}.  This
+means you can use generally available tools like @command{xmllint} to
+check that your feature descriptions are well-formed and valid.
+However, to help people unfamiliar with XML write descriptions for
+their targets, we also describe the grammar here.
+
+At the moment, target descriptions can only describe register sets, to
+be accessed via the remote protocol @code{g}, @code{G}, @code{p} and
+@code{P} requests.  We hope to extend the format to include other
+kinds of information, like memory maps.
+
+Here is a simple sample target description:
+
+@example
+<?xml version="1.0"?>
+<!DOCTYPE target SYSTEM "gdb-target.dtd">
+<target>
+  <feature name="bar">
+    <reg name="s0" bitsize="32"/>
+    <reg name="s1" bitsize="32" type="float"/>
+  </feature>
+
+  <feature-set>
+    <feature-ref name="bar" base-regnum="1"/>
+  </feature-set>
+</target>
+@end example
+
+@noindent
+This describes a simple target feature set which only contains two
+registers, named @code{s0} (a 32-bit integer register) and @code{s1}
+(a 32-bit floating point register).
+
+A target description has the overall form:
+
+@example
+<?xml version="1.0"?>
+<!DOCTYPE target SYSTEM "gdb-target.dtd">
+<target>
+  @var{feature}@dots{}
+  @var{feature-set}
+</target>
+@end example
+
+@noindent
+The description is generally insensitive to whitespace and line
+breaks, under the usual common-sense rules.  The ellipsis
+(@samp{@dots{}}) after @var{feature} indicates that @var{feature} may
+appear zero or more times.
+
+Each @var{feature} names and describes a single feature of the target;
+at the moment, features can only describe register sets.  The
+@var{feature-set} cites particular features by name, pulling together
+a complete description of the target.  A @var{feature} has the form:
+
+@example
+<feature name="@var{name}">
+  @var{reg}@dots{}
+</feature>
+@end example
+
+@noindent
+This defines a feature named @var{name}; each feature's name must be
+unique across the description.
+
+Each @var{reg} has the form:
+
+@example
+<reg name="@var{name}"
+     bitsize="@var{size}"
+     @r{[}regnum="@var{num}"@r{]}
+     @r{[}save-restore="@var{save-restore}"@r{]}
+     @r{[}type="@var{type}"@r{]}
+     @r{[}group="@var{group}"@r{]}/>
+@end example
+
+@noindent
+Items in @r{[}brackets@r{]} are optional.  The components are as follows:
+
+@table @var
+
+@item name
+The register's name; it must be unique within the target description.
+
+@item bitsize
+The register's size, in bits.
+
+@item regnum
+The register's number.  If omitted, a register's number is one greater
+than that of the previous register; the first register's number
+defaults to zero.  But also see the @code{feature-ref} element's
+@code{base-regnum} attribute, below---these register numbers are relative
+to the @code{base-regnum}.
+
+@item save-restore
+Whether the register should be preserved across inferior function
+calls; this must be either @code{yes} or @code{no}.  The default is
+@code{yes}.
+
+@item type
+The type of the register.  At the moment, @var{type} must be either
+@code{int} or @code{float}.  The default is @code{int}.
+
+@item group
+The register group to which this register belongs.  At the moment,
+@var{group} must be either @code{general}, @code{float}, or
+@code{vector}.  If no @var{group} is specified, @value{GDBN} will
+select a register group based on the register's type.
+
+@end table
+
+A @var{feature-set} binds together a set of features to describe
+a complete target.  There can be only one @var{feature-set} in a
+target.  Each @var{feature-set} has the form:
+
+@example
+<feature-set>
+  @var{feature-ref}@dots{}
+</feature-set>
+@end example
+
+@noindent
+where each @var{feature-ref} has the form:
+
+@example
+<feature-ref name="@var{name}" @r{[}base-regnum="@var{n}"@r{]}/>
+@end example
+
+@noindent
+This means that the target includes the feature named @var{name}.  If
+the @code{base-regnum} is present, that means that registers in the
+given feature are numbered starting with @var{n}, until overridden by
+an explicit register number.
+
+It can sometimes be valuable to split a target description up into
+several different annexes, either for organizational purposes, or to
+allow @value{GDBN} to cache portions of the description that change
+rarely.  To make this possible, you can replace any feature
+description with an inclusion directive of the form:
+
+@example
+<xi:include href="@var{annex}"/>
+@end example
+
+@noindent
+When @value{GDBN} encounters an element of this form, it will retrieve
+the annex named @var{annex} (or use its cached copy), and replace the
+inclusion directive with the contents of that annex.
+
 @include gpl.texi
 
 @raisesections
diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c
index b83597c..526c85c 100644
--- a/gdb/f-valprint.c
+++ b/gdb/f-valprint.c
@@ -71,7 +71,7 @@
   switch (TYPE_ARRAY_LOWER_BOUND_TYPE (type))
     {
     case BOUND_BY_VALUE_ON_STACK:
-      current_frame_addr = get_frame_base (deprecated_selected_frame);
+      current_frame_addr = get_frame_base (get_selected_frame (NULL));
       if (current_frame_addr > 0)
 	{
 	  *lower_bound =
@@ -95,7 +95,7 @@
       break;
 
     case BOUND_BY_REF_ON_STACK:
-      current_frame_addr = get_frame_base (deprecated_selected_frame);
+      current_frame_addr = get_frame_base (get_selected_frame (NULL));
       if (current_frame_addr > 0)
 	{
 	  ptr_to_lower_bound =
@@ -129,7 +129,7 @@
   switch (TYPE_ARRAY_UPPER_BOUND_TYPE (type))
     {
     case BOUND_BY_VALUE_ON_STACK:
-      current_frame_addr = get_frame_base (deprecated_selected_frame);
+      current_frame_addr = get_frame_base (get_selected_frame (NULL));
       if (current_frame_addr > 0)
 	{
 	  *upper_bound =
@@ -158,7 +158,7 @@
       break;
 
     case BOUND_BY_REF_ON_STACK:
-      current_frame_addr = get_frame_base (deprecated_selected_frame);
+      current_frame_addr = get_frame_base (get_selected_frame (NULL));
       if (current_frame_addr > 0)
 	{
 	  ptr_to_upper_bound =
@@ -643,10 +643,7 @@
      first make sure that it is visible and if so, let 
      us display its contents */
 
-  fi = deprecated_selected_frame;
-
-  if (fi == NULL)
-    error (_("No frame selected"));
+  fi = get_selected_frame (_("No frame selected"));
 
   /* The following is generally ripped off from stack.c's routine 
      print_frame_info() */
@@ -735,10 +732,7 @@
   if (comname == NULL)
     error (_("Cannot deal with NULL common name!"));
 
-  fi = deprecated_selected_frame;
-
-  if (fi == NULL)
-    error (_("No frame selected"));
+  fi = get_selected_frame (_("No frame selected"));
 
   /* The following is generally ripped off from stack.c's routine 
      print_frame_info() */
diff --git a/gdb/features/feature_to_c.sh b/gdb/features/feature_to_c.sh
new file mode 100644
index 0000000..c757d61
--- /dev/null
+++ b/gdb/features/feature_to_c.sh
@@ -0,0 +1,60 @@
+#!/bin/sh
+
+output=$1
+shift
+
+if test -z "$output" || test -z "$1"; then
+  echo "Usage: $0 OUTPUTFILE INPUTFILE..."
+  exit 1
+fi
+
+if test -e "$output"; then
+  echo "Output file \"$output\" already exists; refusing to overwrite."
+  exit 1
+fi
+
+for input in dummy "$@"; do
+  if test $input != dummy; then
+    arrayname=xml_feature_`echo $input | sed 's,.*/,,; s/[-.]/_/g'`
+
+    gawk 'BEGIN { n = 0
+      print "static const char '$arrayname'[] = {"
+      for (i = 0; i < 255; i++)
+        _ord_[sprintf("%c", i)] = i
+    } {
+      split($0, line, "");
+      printf "  "
+      for (i = 1; i <= length($0); i++) {
+        c = line[i]
+        if (c == "'\''") {
+          printf "'\''\\'\'''\'', "
+        } else if (c == "\\") {
+          printf "'\''\\\\'\'', "
+        } else if (match (c, "[[:print:]]") != 0) {
+          printf "'\''" c "'\'', "
+        } else {
+          printf "'\''\\%03o'\'', ", _ord_[c]
+        }
+        if (i % 10 == 0)
+          printf "\n   "
+      }
+      printf "'\''\\n'\'', \n"
+    } END {
+      print "  0 };"
+    }' < $input >> $output
+  fi
+done
+
+echo >> $output
+echo "const char *const xml_builtin[][2] = {" >> $output
+
+for input in dummy "$@"; do
+  if test $input != dummy; then
+    basename=`echo $input | sed 's,.*/,,'`
+    arrayname=xml_feature_`echo $input | sed 's,.*/,,; s/[-.]/_/g'`
+    echo "  { \"$basename\", $arrayname }," >> $output
+  fi
+done
+
+echo "  { 0, 0 }" >> $output
+echo "};" >> $output
diff --git a/gdb/features/gdb-target.dtd b/gdb/features/gdb-target.dtd
new file mode 100644
index 0000000..6e01b70
--- /dev/null
+++ b/gdb/features/gdb-target.dtd
@@ -0,0 +1,54 @@
+<!-- The root element of a GDB target description is <target>.  It
+     contains a list of feature definitions, followed by a feature-set.
+     This is also the only point at which xi:include is supported;
+     it must be used with xpointer to fetch a feature, from a
+     document whose root element is either target or feature.  -->
+
+<!ELEMENT target	(feature*, feature-set)>
+<!ATTLIST target
+	xmlns:xi	CDATA	#FIXED "http://www.w3.org/2001/XInclude">
+
+<!ELEMENT feature-set	(description*, feature-ref+)>
+
+<!-- QUESTION: Is there any reason for feature-ref to have its own
+     descriptions?  Or a short name field (descriptive)?  -->
+<!ELEMENT feature-ref	EMPTY>
+<!ATTLIST feature-ref
+	name		IDREF	#REQUIRED
+	base-regnum	CDATA	#IMPLIED>
+
+<!-- TODO: Handle arch_data, maybe as unvalidated fields; do we want
+    to define a namespace for arch-specific fields?  Issue for feature
+    and for reg.  -->
+
+<!-- QUESTION: Should the feature also have a short description to identify
+     it?  The format of its "name" field is restricted and probably not
+     user-appropriate.  -->
+<!ELEMENT feature	(description*, reg*)>
+<!ATTLIST feature
+	name		ID	#REQUIRED>
+
+<!-- TODO: GDB does not yet support descriptions.  -->
+
+<!-- Registers are not required to have an explicit register number field;
+     they are numbered sequentially starting at zero.  If a register does
+     have an explicit number, the next register will be assigned the next
+     sequential number by default.  When the feature is referenced, register
+     numbers are adjusted by the reference's base-regnum.  -->
+<!-- arch_data; see above -->
+<!-- TODO: Allow save-restore default to be specified by the feature?
+     Computation coprocessors should generally be saved and restored,
+     but system control coprocessors generally shouldn't.  -->
+<!ELEMENT reg		(description*)>
+<!ATTLIST reg
+	name		CDATA	#REQUIRED
+	bitsize		CDATA	#REQUIRED
+	regnum		CDATA	#IMPLIED
+	save-restore	(yes | no) 'yes'
+	type		CDATA	'int'
+	group		CDATA	#IMPLIED
+	>
+
+<!ELEMENT description	(#PCDATA)>
+<!ATTLIST description
+	xml:lang	CDATA	#IMPLIED>
diff --git a/gdb/frame.c b/gdb/frame.c
index 64e1baf..80814fb 100644
--- a/gdb/frame.c
+++ b/gdb/frame.c
@@ -395,16 +395,26 @@
 {
   struct frame_info *frame;
 
+#if 0
   /* ZERO denotes the null frame, let the caller decide what to do
      about it.  Should it instead return get_current_frame()?  */
   if (!frame_id_p (id))
     return NULL;
+#endif
 
   for (frame = get_current_frame ();
        frame != NULL;
        frame = get_prev_frame (frame))
     {
       struct frame_id this = get_frame_id (frame);
+#if 1
+      /* We use an invalid frame id to mean "could not unwind from
+	 here"!  This hack fixes the "value being assigned to is
+	 no longer active" problem.  This strongly suggests that
+	 we need to change the representation.  */
+      if (!frame_id_p (id) && !frame_id_p (this))
+	return frame;
+#endif
       if (frame_id_eq (id, this))
 	/* An exact match.  */
 	return frame;
diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c
index 4fa5ea4..c3959db 100644
--- a/gdb/gdbarch.c
+++ b/gdb/gdbarch.c
@@ -41,6 +41,7 @@
 #include "gdbcmd.h"
 #include "inferior.h" /* enum CALL_DUMMY_LOCATION et.al. */
 #include "symcat.h"
+#include "available.h"
 
 #include "floatformat.h"
 
@@ -235,6 +236,8 @@
   gdbarch_register_reggroup_p_ftype *register_reggroup_p;
   gdbarch_fetch_pointer_argument_ftype *fetch_pointer_argument;
   gdbarch_regset_from_core_section_ftype *regset_from_core_section;
+  int available_features_support;
+  struct gdb_feature_set * feature_set;
 };
 
 
@@ -361,6 +364,8 @@
   default_register_reggroup_p,  /* register_reggroup_p */
   0,  /* fetch_pointer_argument */
   0,  /* regset_from_core_section */
+  0,  /* available_features_support */
+  0,  /* feature_set */
   /* startup_gdbarch() */
 };
 
@@ -719,6 +724,9 @@
   fprintf_unfiltered (file,
                       "gdbarch_dump: adjust_breakpoint_address = <0x%lx>\n",
                       (long) current_gdbarch->adjust_breakpoint_address);
+  fprintf_unfiltered (file,
+                      "gdbarch_dump: available_features_support = %s\n",
+                      paddr_d (current_gdbarch->available_features_support));
 #ifdef BELIEVE_PCC_PROMOTION
   fprintf_unfiltered (file,
                       "gdbarch_dump: BELIEVE_PCC_PROMOTION # %s\n",
@@ -1054,6 +1062,9 @@
   fprintf_unfiltered (file,
                       "gdbarch_dump: extract_return_value = <0x%lx>\n",
                       (long) current_gdbarch->extract_return_value);
+  fprintf_unfiltered (file,
+                      "gdbarch_dump: feature_set = %s\n",
+                      paddr_nz ((long) current_gdbarch->feature_set));
 #ifdef FETCH_POINTER_ARGUMENT_P
   fprintf_unfiltered (file,
                       "gdbarch_dump: %s # %s\n",
@@ -1640,6 +1651,14 @@
   return gdbarch->tdep;
 }
 
+struct obstack *
+gdbarch_obstack (struct gdbarch *gdbarch)
+{
+  if (gdbarch_debug >= 2)
+    fprintf_unfiltered (gdb_stdlog, "gdbarch_obstack called\n");
+  return gdbarch->obstack;
+}
+
 
 const struct bfd_arch_info *
 gdbarch_bfd_arch_info (struct gdbarch *gdbarch)
@@ -3683,6 +3702,38 @@
   gdbarch->regset_from_core_section = regset_from_core_section;
 }
 
+int
+gdbarch_available_features_support (struct gdbarch *gdbarch)
+{
+  gdb_assert (gdbarch != NULL);
+  if (gdbarch_debug >= 2)
+    fprintf_unfiltered (gdb_stdlog, "gdbarch_available_features_support called\n");
+  return gdbarch->available_features_support;
+}
+
+void
+set_gdbarch_available_features_support (struct gdbarch *gdbarch,
+                                        int available_features_support)
+{
+  gdbarch->available_features_support = available_features_support;
+}
+
+struct gdb_feature_set *
+gdbarch_feature_set (struct gdbarch *gdbarch)
+{
+  gdb_assert (gdbarch != NULL);
+  if (gdbarch_debug >= 2)
+    fprintf_unfiltered (gdb_stdlog, "gdbarch_feature_set called\n");
+  return gdbarch->feature_set;
+}
+
+void
+set_gdbarch_feature_set (struct gdbarch *gdbarch,
+                         struct gdb_feature_set * feature_set)
+{
+  gdbarch->feature_set = feature_set;
+}
+
 
 /* Keep a registry of per-architecture data-pointers required by GDB
    modules. */
@@ -3895,8 +3946,9 @@
 }
 
 static void
-current_gdbarch_swap_in_hack (struct gdbarch *new_gdbarch)
+current_gdbarch_swap_in_hack (void *argument)
 {
+  struct gdbarch *new_gdbarch = argument;
   struct gdbarch_swap *curr;
 
   gdb_assert (current_gdbarch == NULL);
@@ -4006,8 +4058,7 @@
 }
 
 
-/* Look for an architecture using gdbarch_info.  Base search on only
-   BFD_ARCH_INFO and BYTE_ORDER. */
+/* Look for an architecture using gdbarch_info.  */
 
 struct gdbarch_list *
 gdbarch_list_lookup_by_info (struct gdbarch_list *arches,
@@ -4021,6 +4072,15 @@
 	continue;
       if (info->osabi != arches->gdbarch->osabi)
 	continue;
+
+      if (info->feature_set && !arches->gdbarch->feature_set)
+	continue;
+      if (!info->feature_set && arches->gdbarch->feature_set)
+	continue;
+      if (info->feature_set
+	  && !features_same_p (info->feature_set, arches->gdbarch->feature_set))
+	continue;
+
       return arches;
     }
   return NULL;
@@ -4173,13 +4233,18 @@
      architecture of the same family is found at the head of the
      rego->arches list.  */
   struct gdbarch *old_gdbarch = current_gdbarch_swap_out_hack ();
+  struct cleanup *back_to;
+
+  /* Make sure we restore current_gdbarch on our way out if an error
+     occurs.  */
+  back_to = make_cleanup (current_gdbarch_swap_in_hack, old_gdbarch);
 
   /* Find the specified architecture.  */
   struct gdbarch *new_gdbarch = find_arch_by_info (old_gdbarch, info);
 
   /* Restore the existing architecture.  */
   gdb_assert (current_gdbarch == NULL);
-  current_gdbarch_swap_in_hack (old_gdbarch);
+  do_cleanups (back_to);
 
   return new_gdbarch;
 }
diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h
index 75ac81f..dc1b1a9 100644
--- a/gdb/gdbarch.h
+++ b/gdb/gdbarch.h
@@ -49,6 +49,7 @@
 struct disassemble_info;
 struct target_ops;
 struct obstack;
+struct gdb_feature_set;
 
 extern struct gdbarch *current_gdbarch;
 
@@ -1403,8 +1404,19 @@
 extern const struct regset * gdbarch_regset_from_core_section (struct gdbarch *gdbarch, const char *sect_name, size_t sect_size);
 extern void set_gdbarch_regset_from_core_section (struct gdbarch *gdbarch, gdbarch_regset_from_core_section_ftype *regset_from_core_section);
 
+/* Non-zero if the architecture supports target feature sets. */
+
+extern int gdbarch_available_features_support (struct gdbarch *gdbarch);
+extern void set_gdbarch_available_features_support (struct gdbarch *gdbarch, int available_features_support);
+
+/* The architecture's currently associated feature set. */
+
+extern struct gdb_feature_set * gdbarch_feature_set (struct gdbarch *gdbarch);
+extern void set_gdbarch_feature_set (struct gdbarch *gdbarch, struct gdb_feature_set * feature_set);
+
 extern struct gdbarch_tdep *gdbarch_tdep (struct gdbarch *gdbarch);
 
+extern struct obstack *gdbarch_obstack (struct gdbarch *gdbarch);
 
 /* Mechanism for co-ordinating the selection of a specific
    architecture.
@@ -1487,6 +1499,9 @@
 
   /* Use default: GDB_OSABI_UNINITIALIZED (-1).  */
   enum gdb_osabi osabi;
+
+  /* Use default: NULL.  */
+  struct gdb_feature_set *feature_set;
 };
 
 typedef struct gdbarch *(gdbarch_init_ftype) (struct gdbarch_info info, struct gdbarch_list *arches);
@@ -1511,11 +1526,11 @@
 /* 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);
+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
+   basic initialization using values obtained from the INFO and TDEP
    parameters.  set_gdbarch_*() functions are called to complete the
    initialization of the object. */
 
diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh
index afcfd82..39914dd 100755
--- a/gdb/gdbarch.sh
+++ b/gdb/gdbarch.sh
@@ -662,6 +662,12 @@
 # Return the appropriate register set for a core file section with
 # name SECT_NAME and size SECT_SIZE.
 M::const struct regset *:regset_from_core_section:const char *sect_name, size_t sect_size:sect_name, sect_size
+
+# Non-zero if the architecture supports target feature sets.
+v::int:available_features_support
+
+# The architecture's currently associated feature set.
+v::struct gdb_feature_set *:feature_set:::::::paddr_nz ((long) current_gdbarch->feature_set)
 EOF
 }
 
@@ -771,6 +777,7 @@
 struct disassemble_info;
 struct target_ops;
 struct obstack;
+struct gdb_feature_set;
 
 extern struct gdbarch *current_gdbarch;
 EOF
@@ -904,6 +911,7 @@
 
 extern struct gdbarch_tdep *gdbarch_tdep (struct gdbarch *gdbarch);
 
+extern struct obstack *gdbarch_obstack (struct gdbarch *gdbarch);
 
 /* Mechanism for co-ordinating the selection of a specific
    architecture.
@@ -986,6 +994,9 @@
 
   /* Use default: GDB_OSABI_UNINITIALIZED (-1).  */
   enum gdb_osabi osabi;
+
+  /* Use default: NULL.  */
+  struct gdb_feature_set *feature_set;
 };
 
 typedef struct gdbarch *(gdbarch_init_ftype) (struct gdbarch_info info, struct gdbarch_list *arches);
@@ -1010,11 +1021,11 @@
 /* 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);
+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
+   basic initialization using values obtained from the INFO and TDEP
    parameters.  set_gdbarch_*() functions are called to complete the
    initialization of the object. */
 
@@ -1157,6 +1168,7 @@
 #include "gdbcmd.h"
 #include "inferior.h" /* enum CALL_DUMMY_LOCATION et.al. */
 #include "symcat.h"
+#include "available.h"
 
 #include "floatformat.h"
 
@@ -1590,6 +1602,14 @@
     fprintf_unfiltered (gdb_stdlog, "gdbarch_tdep called\\n");
   return gdbarch->tdep;
 }
+
+struct obstack *
+gdbarch_obstack (struct gdbarch *gdbarch)
+{
+  if (gdbarch_debug >= 2)
+    fprintf_unfiltered (gdb_stdlog, "gdbarch_obstack called\\n");
+  return gdbarch->obstack;
+}
 EOF
 printf "\n"
 function_list | while do_read
@@ -1913,8 +1933,9 @@
 }
 
 static void
-current_gdbarch_swap_in_hack (struct gdbarch *new_gdbarch)
+current_gdbarch_swap_in_hack (void *argument)
 {
+  struct gdbarch *new_gdbarch = argument;
   struct gdbarch_swap *curr;
 
   gdb_assert (current_gdbarch == NULL);
@@ -2024,8 +2045,7 @@
 }
 
 
-/* Look for an architecture using gdbarch_info.  Base search on only
-   BFD_ARCH_INFO and BYTE_ORDER. */
+/* Look for an architecture using gdbarch_info.  */
 
 struct gdbarch_list *
 gdbarch_list_lookup_by_info (struct gdbarch_list *arches,
@@ -2039,6 +2059,15 @@
 	continue;
       if (info->osabi != arches->gdbarch->osabi)
 	continue;
+
+      if (info->feature_set && !arches->gdbarch->feature_set)
+	continue;
+      if (!info->feature_set && arches->gdbarch->feature_set)
+	continue;
+      if (info->feature_set
+	  && !features_same_p (info->feature_set, arches->gdbarch->feature_set))
+	continue;
+
       return arches;
     }
   return NULL;
@@ -2191,13 +2220,18 @@
      architecture of the same family is found at the head of the
      rego->arches list.  */
   struct gdbarch *old_gdbarch = current_gdbarch_swap_out_hack ();
+  struct cleanup *back_to;
+
+  /* Make sure we restore current_gdbarch on our way out if an error
+     occurs.  */
+  back_to = make_cleanup (current_gdbarch_swap_in_hack, old_gdbarch);
 
   /* Find the specified architecture.  */
   struct gdbarch *new_gdbarch = find_arch_by_info (old_gdbarch, info);
 
   /* Restore the existing architecture.  */
   gdb_assert (current_gdbarch == NULL);
-  current_gdbarch_swap_in_hack (old_gdbarch);
+  do_cleanups (back_to);
 
   return new_gdbarch;
 }
diff --git a/gdb/ia64-tdep.c b/gdb/ia64-tdep.c
index 4ec5a95..f302142 100644
--- a/gdb/ia64-tdep.c
+++ b/gdb/ia64-tdep.c
@@ -2455,8 +2455,8 @@
 }
 
 /* Call low-level function to access the kernel unwind table.  */
-static int
-getunwind_table (void *buf, size_t len)
+static LONGEST
+getunwind_table (gdb_byte **buf_p)
 {
   LONGEST x;
 
@@ -2467,10 +2467,11 @@
      we want to preserve fall back to the running kernel's table, then
      we should find a way to override the corefile layer's
      xfer_partial method.  */
-  x = target_read_partial (&current_target, TARGET_OBJECT_UNWIND_TABLE, NULL,
-			   buf, 0, len);
 
-  return (int)x;
+  x = target_read_whole (&current_target, TARGET_OBJECT_UNWIND_TABLE,
+			 NULL, buf_p);
+
+  return x;
 }
 
 /* Get the kernel unwind table.  */				 
@@ -2481,14 +2482,15 @@
 
   if (!ktab) 
     {
+      gdb_byte *ktab_buf;
       size_t size;
-      size = getunwind_table (NULL, 0);
-      if ((int)size < 0)
-        return -UNW_ENOINFO;
-      ktab_size = size;
-      ktab = xmalloc (ktab_size);
-      getunwind_table (ktab, ktab_size);
-		          
+
+      ktab_size = getunwind_table (&ktab_buf);
+      if (ktab_size <= 0)
+	return -UNW_ENOINFO;
+      else
+	ktab = (struct ia64_table_entry *) ktab_buf;
+
       for (etab = ktab; etab->start_offset; ++etab)
         etab->info_offset += KERNEL_START;
     }
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index 12a305d..3d18298 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -48,6 +48,9 @@
 #include <ctype.h>
 #include "gdb_assert.h"
 #include "observer.h"
+#include "available.h"
+
+#include "gdb_obstack.h"
 
 /* Functions exported for general use, in inferior.h: */
 
@@ -405,6 +408,27 @@
 void
 post_create_inferior (struct target_ops *target, int from_tty)
 {
+  /* The first thing we do after creating an inferior is update the
+     architecture with information provided by the target.
+
+     FIXME: In some cases we could do this after target_open
+     instead; should we?  */
+  if (gdbarch_available_features_support (current_gdbarch))
+    {
+      struct gdb_feature_set *features;
+      struct obstack tmp_obstack;
+
+      obstack_init (&tmp_obstack);
+      features = target_available_features (target, &tmp_obstack);
+
+      /* Switch to a new architecture.  We must call this even if
+	 the target could not return features; if the previous
+	 target could, we may have the wrong architecture selected.  */
+      arch_set_available_features (features);
+
+      obstack_free (&tmp_obstack, NULL);
+    }
+
   if (exec_bfd)
     {
       /* Sometimes the platform-specific hook loads initial shared
@@ -1284,10 +1308,8 @@
     error (_("The \"finish\" command does not take any arguments."));
   if (!target_has_execution)
     error (_("The program is not running."));
-  if (deprecated_selected_frame == NULL)
-    error (_("No selected frame."));
 
-  frame = get_prev_frame (deprecated_selected_frame);
+  frame = get_prev_frame (get_selected_frame (_("No selected frame.")));
   if (frame == 0)
     error (_("\"finish\" not meaningful in the outermost frame."));
 
@@ -1305,7 +1327,7 @@
 
   /* Find the function we will return from.  */
 
-  function = find_pc_function (get_frame_pc (deprecated_selected_frame));
+  function = find_pc_function (get_frame_pc (get_selected_frame (NULL)));
 
   /* Print info on the selected frame, including level number but not
      source.  */
@@ -1671,13 +1693,12 @@
 
   if (!target_has_registers)
     error (_("The program has no registers now."));
-  if (deprecated_selected_frame == NULL)
-    error (_("No selected frame."));
 
   if (!addr_exp)
     {
       gdbarch_print_registers_info (current_gdbarch, gdb_stdout,
-				    deprecated_selected_frame, -1, fpregs);
+				    get_selected_frame (_("No selected frame.")),
+				    -1, fpregs);
       return;
     }
 
@@ -1710,12 +1731,12 @@
 
       /* A register name?  */
       {
-	int regnum = frame_map_name_to_regnum (deprecated_selected_frame,
+	int regnum = frame_map_name_to_regnum (get_selected_frame (_("No selected frame.")),
 					       start, end - start);
 	if (regnum >= 0)
 	  {
 	    gdbarch_print_registers_info (current_gdbarch, gdb_stdout,
-					  deprecated_selected_frame, regnum, fpregs);
+					  get_selected_frame (NULL), regnum, fpregs);
 	    continue;
 	  }
       }
@@ -1729,7 +1750,7 @@
 	    && regnum < NUM_REGS + NUM_PSEUDO_REGS)
 	  {
 	    gdbarch_print_registers_info (current_gdbarch, gdb_stdout,
-					  deprecated_selected_frame, regnum, fpregs);
+					  get_selected_frame (NULL), regnum, fpregs);
 	    continue;
 	  }
       }
@@ -1755,7 +1776,7 @@
 		if (gdbarch_register_reggroup_p (current_gdbarch, regnum,
 						 group))
 		  gdbarch_print_registers_info (current_gdbarch,
-						gdb_stdout, deprecated_selected_frame,
+						gdb_stdout, get_selected_frame (NULL),
 						regnum, fpregs);
 	      }
 	    continue;
@@ -1785,8 +1806,6 @@
 {
   if (!target_has_registers)
     error (_("The program has no registers now."));
-  if (deprecated_selected_frame == NULL)
-    error (_("No selected frame."));
 
   if (gdbarch_print_vector_info_p (gdbarch))
     gdbarch_print_vector_info (gdbarch, file, frame, args);
@@ -1811,7 +1830,7 @@
 static void
 vector_info (char *args, int from_tty)
 {
-  print_vector_info (current_gdbarch, gdb_stdout, deprecated_selected_frame, args);
+  print_vector_info (current_gdbarch, gdb_stdout, get_selected_frame (NULL), args);
 }
 
 
@@ -1999,8 +2018,6 @@
 {
   if (!target_has_registers)
     error (_("The program has no registers now."));
-  if (deprecated_selected_frame == NULL)
-    error (_("No selected frame."));
 
   if (gdbarch_print_float_info_p (gdbarch))
     gdbarch_print_float_info (gdbarch, file, frame, args);
@@ -2027,7 +2044,7 @@
 float_info (char *args, int from_tty)
 {
   print_float_info (current_gdbarch, gdb_stdout, 
-		    deprecated_selected_frame, args);
+		    get_selected_frame (NULL), args);
 }
 
 static void
diff --git a/gdb/inflow.c b/gdb/inflow.c
index 83a0c9d..1b15d2c 100644
--- a/gdb/inflow.c
+++ b/gdb/inflow.c
@@ -588,7 +588,7 @@
   if (target_has_stack)
     {
       printf_filtered (_("In %s,\n"), target_longname);
-      if (deprecated_selected_frame == NULL)
+      if (deprecated_safe_get_selected_frame () == NULL)
 	fputs_filtered ("No selected stack frame.\n", gdb_stdout);
       else
 	print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC);
diff --git a/gdb/infrun.c b/gdb/infrun.c
index 47fbe09..d4bf889 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -3590,7 +3590,7 @@
 
   inf_status->registers = regcache_dup (current_regcache);
 
-  inf_status->selected_frame_id = get_frame_id (deprecated_selected_frame);
+  inf_status->selected_frame_id = get_frame_id (get_selected_frame (NULL));
   return inf_status;
 }
 
diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c
index 0710ac7..0c1dc1b 100644
--- a/gdb/linux-nat.c
+++ b/gdb/linux-nat.c
@@ -2849,7 +2849,8 @@
       note_data = thread_args.note_data;
     }
 
-  auxv_len = target_auxv_read (&current_target, &auxv);
+  auxv_len = target_read_whole (&current_target, TARGET_OBJECT_AUXV, NULL,
+				&auxv);
   if (auxv_len > 0)
     {
       note_data = elfcore_write_note (obfd, note_data, note_size,
diff --git a/gdb/parse-avail.c b/gdb/parse-avail.c
new file mode 100644
index 0000000..2c56fcb
--- /dev/null
+++ b/gdb/parse-avail.c
@@ -0,0 +1,1281 @@
+/* Support for runtime-defined target features for GDB.
+
+   Copyright (C) 2006
+   Free Software Foundation, Inc.
+
+   Contributed by CodeSourcery.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
+
+#include "defs.h"
+
+#include "available.h"
+#include "sha1.h"
+
+#include "filenames.h"
+#include "gdb_assert.h"
+#include "gdb_string.h"
+#include "gdb_obstack.h"
+
+#include <expat.h>
+
+/* From xml-builtin.c.  */
+extern const char *xml_builtin[][2];
+
+/* Prototypes.  */
+
+static int xml_process_xincludes (char **output_p, const char *text,
+				  xml_fetch_another fetcher, void *fetcher_baton,
+				  int nested);
+
+/* General notes for this file:
+
+   Do not call error while parsing supplied features.  If something is
+   unrecognizable, fail gracefully.  Calling error may lead to a
+   failure to initialize a gdbarch, and internal errors down the road.
+   Also, it's hard to predict with XML what's meaningless today but
+   might make sense tomorrow :-)
+
+   Warnings are OK; so are true internal errors, e.g. impossible states
+   in the parsing finite state machine.  Also, we will reach
+   internal_error if there is a memory allocation failure.  */
+
+/* Parse a field VALSTR that we expect to contain an integer value.
+   The integer is returned in *VALP.
+
+   Returns 0 for success, -1 for error.  */
+
+static int
+xml_parse_one_integer (const char *valstr, long *valp)
+{
+  char *endptr;
+  long result;
+
+  if (*valstr == '\0')
+    return -1;
+
+  result = strtol (valstr, &endptr, 0);
+  if (*endptr != '\0')
+    return -1;
+
+  *valp = result;
+  return 0;
+}
+
+/* Parse a field VALSTR that we expect to contain a boolean value.
+   The value is returned in *VALP.
+
+   Returns 0 for success, -1 for error.  */
+
+static int
+xml_parse_one_boolean (const char *valstr, int *valp)
+{
+  if (strcmp (valstr, "yes") == 0)
+    *valp = 1;
+  else if (strcmp (valstr, "no") == 0)
+    *valp = 0;
+  else
+    return -1;
+
+  return 0;
+}
+
+/* Save STR on OBSTACK, and return the new copy.  */
+
+static char *
+obstrdup (struct obstack *obstack, const char *str)
+{
+  char *result;
+  size_t len;
+
+  len = strlen (str);
+  result = obstack_alloc (obstack, len + 1);
+  memcpy (result, str, len);
+  result[len] = '\0';
+
+  return result;
+}
+
+/* Duplicate a provided ORIG_FEATURE, allocating the new copy from
+   OBSTACK.  Return the new copy.  */
+
+static struct gdb_available_feature *
+copy_feature_to_obstack (struct obstack *obstack,
+			 const struct gdb_available_feature *orig_feature)
+{
+  struct gdb_available_feature *feature;
+  struct gdb_available_register **reg_slot, *orig_reg;
+
+  feature = OBSTACK_ZALLOC (obstack, struct gdb_available_feature);
+
+  memcpy (feature, orig_feature, sizeof (struct gdb_available_feature));
+  feature->name = obstrdup (obstack, feature->name);
+  if (feature->arch_data)
+    feature->arch_data = obstrdup (obstack, feature->arch_data);
+
+  reg_slot = &feature->registers;
+  for (orig_reg = orig_feature->registers;
+       orig_reg;
+       orig_reg = orig_reg->next)
+    {
+      struct gdb_available_register *reg;
+
+      reg = OBSTACK_ZALLOC (obstack, struct gdb_available_register);
+      *reg_slot = reg;
+      reg_slot = &reg->next;
+
+      memcpy (reg, orig_reg, sizeof (struct gdb_available_register));
+      reg->name = obstrdup (obstack, reg->name);
+      if (reg->arch_data)
+	reg->arch_data = obstrdup (obstack, reg->arch_data);
+      if (reg->group)
+	reg->group = obstrdup (obstack, reg->group);
+      if (reg->type)
+	reg->type = obstrdup (obstack, reg->type);
+    }
+
+  return feature;
+}
+
+
+
+/* FIXME item: Warnings versus errors?  Where to issue warnings?  */
+
+enum xml_phase {
+  PHASE_TOP,
+  PHASE_IN_TARGET,
+  PHASE_IN_FEATURE,
+  PHASE_IN_DESCRIPTION,
+  PHASE_IN_REG,
+  PHASE_IN_FEATURE_SET,
+  PHASE_IN_FEATURE_REF,
+  PHASE_UNKNOWN
+};
+
+struct xml_state_stack
+{
+  enum xml_phase phase;
+
+  union
+  {
+    struct
+    {
+      int seen_target;
+      int nested;
+    } top;
+    struct
+    {
+      int seen_feature_set;
+      int features_only;
+    } target;
+    struct
+    {
+      struct gdb_available_feature *feature;
+      int seen_reg;
+    } feature;
+    struct
+    {
+      struct gdb_available_register *reg;
+    } reg;
+    struct
+    {
+      int depth;
+    } unknown;
+  } u;
+
+  struct xml_state_stack *prev;
+};
+
+struct xml_feature_parse_data
+{
+  /* The obstack to allocate new features from.  */
+  struct obstack *obstack;
+
+  struct gdb_available_feature *seen_features;
+
+  struct gdb_available_feature *target_features;
+
+  /* Rough count of unrecognized or invalid items found while
+     processing.  These are non-fatal; however, some data from the
+     input has been skipped.  */
+  int unhandled;
+
+  struct xml_state_stack *state;
+};
+
+static void
+xml_start_feature (struct xml_feature_parse_data *data,
+		   const XML_Char **attrs)
+{
+  struct gdb_available_feature *feature;
+  const XML_Char **p;
+
+  feature = obstack_alloc (data->obstack,
+			   sizeof (struct gdb_available_feature));
+  memset (feature, 0, sizeof (struct gdb_available_feature));
+
+  feature->protocol_number = -1;
+
+  for (p = attrs; *p; p += 2)
+    {
+      const char *name = p[0];
+      const char *val = p[1];
+
+      if (strcmp (name, "name") == 0)
+	feature->name = obstrdup (data->obstack, val);
+
+      else
+	data->unhandled++;
+    }
+
+  /* Verify that mandatory fields were supplied.  */
+  if (feature->name == NULL)
+    {
+      data->unhandled++;
+      return;
+    }
+
+  data->state->u.feature.feature = feature;
+}
+
+static void
+xml_start_reg (struct xml_feature_parse_data *data,
+	       const XML_Char **attrs)
+{
+  struct gdb_available_register *reg;
+  const XML_Char **p;
+
+  reg = obstack_alloc (data->obstack,
+		       sizeof (struct gdb_available_register));
+  memset (reg, 0, sizeof (struct gdb_available_register));
+
+  reg->gdb_regnum = -1;
+  reg->protocol_number = -1;
+  reg->bitsize = -1;
+  reg->save_restore = -1;
+
+  for (p = attrs; *p; p += 2)
+    {
+      const char *name = p[0];
+      const char *val = p[1];
+
+      if (*val == 0)
+	data->unhandled++;
+
+      else if (strcmp (name, "name") == 0)
+	reg->name = obstrdup (data->obstack, val);
+
+      else if (strcmp (name, "regnum") == 0)
+	{
+	  if (xml_parse_one_integer (val, &reg->protocol_number) < 0)
+	    data->unhandled++;
+	}
+
+      else if (strcmp (name, "bitsize") == 0)
+	{
+	  if (xml_parse_one_integer (val, &reg->bitsize) < 0)
+	    data->unhandled++;
+	}
+
+      else if (strcmp (name, "type") == 0)
+	reg->type = obstrdup (data->obstack, val);
+
+      else if (strcmp (name, "group") == 0)
+	reg->group = obstrdup (data->obstack, val);
+
+      else if (strcmp (name, "save-restore") == 0)
+	{
+	  if (xml_parse_one_boolean (val, &reg->save_restore) < 0)
+	    data->unhandled++;
+	}
+
+      else
+	data->unhandled++;
+    }
+
+  /* Fill in optional fields with defaults.  */
+  /* FIXME: Now that we always provide the DTD, we may not need to do
+     this; that would make these into internal errors.  */
+  if (reg->save_restore == -1)
+    reg->save_restore = 1;
+  if (reg->type == NULL)
+    reg->type = obstrdup (data->obstack, "int");
+
+  /* Verify that mandatory fields were supplied.  */
+  if (reg->name == NULL || reg->bitsize == -1)
+    {
+      data->unhandled++;
+      return;
+    }
+
+  data->state->u.reg.reg = reg;
+}
+
+static void
+xml_start_feature_ref (struct xml_feature_parse_data *data,
+		       const XML_Char **attrs)
+{
+  struct gdb_available_feature *feature, *new_feature;
+  struct gdb_available_register *reg;
+  const XML_Char **p;
+  const char *feature_name = NULL;
+  int i;
+
+  for (p = attrs; *p; p += 2)
+    {
+      const char *name = p[0];
+      const char *val = p[1];
+
+      if (strcmp (name, "name") == 0)
+	{
+	  feature_name = val;
+	  break;
+	}
+    }
+
+  if (feature_name == NULL)
+    {
+      data->unhandled++;
+      return;
+    }
+
+  for (feature = data->seen_features; feature; feature = feature->next)
+    if (strcmp (feature->name, feature_name) == 0)
+      break;
+
+  /* TODO: Look for the feature elsewhere - on the target and in our
+     database.  */
+
+  /* If we couldn't find the feature, stop.  */
+  if (feature == NULL)
+    {
+      data->unhandled++;
+      return;
+    }
+
+  new_feature = copy_feature_to_obstack (data->obstack, feature);
+
+  new_feature->protocol_number = -1;
+
+  for (p = attrs; *p; p += 2)
+    {
+      const char *name = p[0];
+      const char *val = p[1];
+
+      if (strcmp (name, "name") == 0)
+	continue;
+      else if (strcmp (name, "base-regnum") == 0)
+	new_feature->protocol_number = strtol (val, NULL, 0);
+      else
+	data->unhandled++;
+    }
+
+  /* The protocol number is only optional if there are no registers.  */
+  if (new_feature->protocol_number == -1 && new_feature->registers != NULL)
+    {
+      data->unhandled++;
+      return;
+    }
+
+  /* Set register numbers in the new feature.  */
+  for (reg = new_feature->registers; reg != NULL; reg = reg->next)
+    reg->protocol_number += new_feature->protocol_number;
+
+  new_feature->next = data->target_features;
+  data->target_features = new_feature;
+}
+
+static void XMLCALL
+xml_feature_start_element (void *data_, const XML_Char *name,
+			   const XML_Char **attrs)
+{
+  struct xml_feature_parse_data *data = data_;
+  const XML_Char **p;
+  struct xml_state_stack *next_state;
+  enum xml_phase next_phase;
+
+  if (data->state->phase == PHASE_UNKNOWN)
+    {
+#if 0
+      fprintf_unfiltered (gdb_stderr, "skipping, name %s\n", name);
+#endif
+      data->state->u.unknown.depth++;
+      return;
+    }
+
+#if 0
+  fprintf_unfiltered (gdb_stderr, "entering, name %s\n", name);
+  for (p = attrs; *p; p += 2)
+    fprintf_unfiltered (gdb_stderr, "  attr %s=\"%s\"\n", p[0], p[1]);
+#endif
+
+  next_state = xmalloc (sizeof (struct xml_state_stack));
+  memset (next_state, 0, sizeof (struct xml_state_stack));
+
+  /* Map the element we're entering to our known elements.  */
+  if (strcmp (name, "target") == 0)
+    next_phase = PHASE_IN_TARGET;
+  else if (strcmp (name, "feature") == 0)
+    next_phase = PHASE_IN_FEATURE;
+  else if (strcmp (name, "description") == 0)
+    next_phase = PHASE_IN_DESCRIPTION;
+  else if (strcmp (name, "reg") == 0)
+    next_phase = PHASE_IN_REG;
+  else if (strcmp (name, "feature-set") == 0)
+    next_phase = PHASE_IN_FEATURE_SET;
+  else if (strcmp (name, "feature-ref") == 0)
+    next_phase = PHASE_IN_FEATURE_REF;
+  else
+    next_phase = PHASE_UNKNOWN;
+
+  /* Make sure that the next phase is sensible.  */
+  switch (data->state->phase)
+    {
+    case PHASE_TOP:
+      if (next_phase == PHASE_IN_TARGET
+	  && !data->state->u.top.seen_target)
+	{
+	  data->state->u.top.seen_target = 1;
+	  break;
+	}
+      if (next_phase == PHASE_IN_FEATURE
+	  && !data->state->u.top.seen_target
+	  && data->state->u.top.nested)
+	{
+	  data->state->u.top.seen_target = 1;
+	  break;
+	}
+      next_phase = PHASE_UNKNOWN;
+      break;
+
+    case PHASE_IN_TARGET:
+      if (next_phase == PHASE_IN_FEATURE
+	  && !data->state->u.target.seen_feature_set)
+	break;
+      if (next_phase == PHASE_IN_FEATURE_SET
+	  && !data->state->u.target.seen_feature_set)
+	{
+	  if (data->state->u.target.features_only)
+	    {
+	      /* Skip parsing the feature set.  This is not an
+		 error, so counteract the increment of data->unhandled
+		 below.  */
+	      next_phase = PHASE_UNKNOWN;
+	      data->unhandled--;
+	    }
+
+	  data->state->u.target.seen_feature_set = 1;
+	  break;
+	}
+      next_phase = PHASE_UNKNOWN;
+      break;
+
+    case PHASE_IN_FEATURE:
+      if (next_phase == PHASE_IN_DESCRIPTION
+	  && !data->state->u.feature.seen_reg)
+	break;
+      if (next_phase == PHASE_IN_REG)
+	{
+	  data->state->u.feature.seen_reg = 1;
+	  break;
+	}
+      next_phase = PHASE_UNKNOWN;
+      break;
+
+    case PHASE_IN_DESCRIPTION:
+      next_phase = PHASE_UNKNOWN;
+      break;
+
+    case PHASE_IN_REG:
+      if (next_phase == PHASE_IN_DESCRIPTION)
+	break;
+      next_phase = PHASE_UNKNOWN;
+      break;
+
+    case PHASE_IN_FEATURE_SET:
+      if (next_phase == PHASE_IN_FEATURE_REF)
+	break;
+      next_phase = PHASE_UNKNOWN;
+      break;
+
+    case PHASE_IN_FEATURE_REF:
+      next_phase = PHASE_UNKNOWN;
+      break;
+
+    case PHASE_UNKNOWN:
+    default:
+      internal_error (__FILE__, __LINE__, "unexpected current state");
+      break;
+    }
+
+  next_state->phase = next_phase;
+  next_state->prev = data->state;
+  data->state = next_state;
+
+  /* FIXME: Check for unknown attributes in more elements, e.g. target.  */
+  /* FIXME: Check for missing mandatory elements more thoroughly.  */
+
+  switch (next_phase)
+    {
+    case PHASE_TOP:
+      internal_error (__FILE__, __LINE__, "unexpected next state");
+      break;
+
+    case PHASE_IN_TARGET:
+      if (data->state->prev->u.top.nested)
+	data->state->u.target.features_only = 1;
+      break;
+
+    case PHASE_IN_FEATURE:
+      xml_start_feature (data, attrs);
+      break;
+
+    case PHASE_IN_DESCRIPTION:
+      /* FIXME: Currently, descriptions are ignored.  */
+      break;
+
+    case PHASE_IN_REG:
+      xml_start_reg (data, attrs);
+      break;
+
+    case PHASE_IN_FEATURE_SET:
+      /* Nothing needed.  */
+      break;
+
+    case PHASE_IN_FEATURE_REF:
+      xml_start_feature_ref (data, attrs);
+      break;
+
+    case PHASE_UNKNOWN:
+      data->unhandled++;
+      next_state->u.unknown.depth++;
+      break;
+
+    default:
+      internal_error (__FILE__, __LINE__, "unexpected next state");
+      break;
+    }
+}
+
+static void XMLCALL
+xml_feature_end_element (void *data_, const XML_Char *name)
+{
+  struct xml_feature_parse_data *data = data_;
+  struct xml_state_stack *state;
+  struct gdb_available_feature *feature;
+  struct gdb_available_register *reg;
+
+#if 0
+  fprintf_unfiltered (gdb_stderr, "leaving, name %s\n", name);
+#endif
+
+  switch (data->state->phase)
+    {
+    case PHASE_UNKNOWN:
+      data->state->u.unknown.depth--;
+      if (data->state->u.unknown.depth)
+	return;
+      break;
+
+    case PHASE_IN_TARGET:
+      break;
+
+    case PHASE_IN_FEATURE:
+      feature = data->state->u.feature.feature;
+
+      /* Do nothing if a fatal error occured.  */
+      if (feature == NULL)
+	break;
+
+      /* Record the feature.  */
+      feature->next = data->seen_features;
+      data->seen_features = feature;
+
+      if (feature->registers)
+	{
+	  /* Reverse the list of registers.  */
+	  struct gdb_available_register *reg1, *reg2, *reg3;
+	  int next;
+
+	  reg1 = NULL;
+	  reg2 = feature->registers;
+
+	  while (reg2)
+	    {
+	      reg3 = reg2->next;
+	      reg2->next = reg1;
+	      reg1 = reg2;
+	      reg2 = reg3;
+	    }
+
+	  feature->registers = reg1;
+
+	  next = 0;
+	  for (reg1 = feature->registers; reg1; reg1 = reg1->next)
+	    if (reg1->protocol_number == -1)
+	      reg1->protocol_number = next++;
+	    else
+	      next = reg1->protocol_number + 1;
+	}
+
+      break;
+
+    case PHASE_IN_DESCRIPTION:
+      /* FIXME: Currently, descriptions are ignored.  */
+      break;
+
+    case PHASE_IN_REG:
+      gdb_assert (data->state->prev->phase == PHASE_IN_FEATURE);
+
+      feature = data->state->prev->u.feature.feature;
+      reg = data->state->u.reg.reg;
+
+      /* Do nothing if a fatal error occured, either here
+	 or in the containing feature.  */
+      if (reg == NULL || feature == NULL)
+	break;
+
+      reg->next = feature->registers;
+      feature->registers = reg;
+      break;
+
+    case PHASE_IN_FEATURE_SET:
+      /* Reverse the list of features.  */
+      if (data->target_features)
+	{
+	  struct gdb_available_feature *feat1, *feat2, *feat3;
+
+	  feat1 = NULL;
+	  feat2 = data->target_features;
+
+	  while (feat2)
+	    {
+	      feat3 = feat2->next;
+	      feat2->next = feat1;
+	      feat1 = feat2;
+	      feat2 = feat3;
+	    }
+
+	  data->target_features = feat1;
+	}
+      break;
+
+    case PHASE_IN_FEATURE_REF:
+      /* Nothing needed.  */
+      break;
+
+    case PHASE_TOP:
+    default:
+      internal_error (__FILE__, __LINE__, "unexpected ending state");
+      break;
+    }
+
+  state = data->state;
+  data->state = data->state->prev;
+  xfree (state);
+}
+
+static void
+xml_parser_cleanup (void *parser)
+{
+  struct xml_feature_parse_data *data;
+
+  data = XML_GetUserData (parser);
+  if (data)
+    {
+      while (data->state)
+	{
+	  struct xml_state_stack *prev;
+
+	  prev = data->state->prev;
+	  xfree (data->state);
+	  data->state = prev;
+	}
+
+      xfree (data);
+    }
+
+  XML_ParserFree (parser);
+}
+
+static int XMLCALL
+xml_fetch_external_entity (XML_Parser parser,
+			   const XML_Char *context,
+			   const XML_Char *base,
+			   const XML_Char *systemId,
+			   const XML_Char *publicId)
+{
+  XML_Parser entity_parser;
+  const char *text;
+  struct cleanup *back_to;
+
+  if (publicId != NULL)
+    return XML_STATUS_ERROR;
+
+  if (systemId != NULL && strcmp (systemId, "gdb-target.dtd") != 0)
+    return XML_STATUS_ERROR;
+
+  text = fetch_xml_builtin ("gdb-target.dtd");
+  if (text == NULL)
+    internal_error (__FILE__, __LINE__, "could not locate built-in DTD");
+
+  entity_parser = XML_ExternalEntityParserCreate (parser, context, NULL);
+  back_to = make_cleanup (xml_parser_cleanup, entity_parser);
+
+  /* Don't use our handlers for the contents of the DTD.  */
+  XML_SetElementHandler (entity_parser, NULL, NULL);
+  XML_SetDoctypeDeclHandler (entity_parser, NULL, NULL);
+  XML_SetXmlDeclHandler (entity_parser, NULL);
+  XML_SetDefaultHandler (entity_parser, NULL);
+  XML_SetUserData (entity_parser, NULL);
+
+  if (XML_Parse (entity_parser, text, strlen (text), 1) != XML_STATUS_OK)
+    {
+      do_cleanups (back_to);
+      return XML_STATUS_ERROR;
+    }
+
+  do_cleanups (back_to);
+  return XML_STATUS_OK;
+}
+
+/* FIXME: Error check more XML_* calls.  */
+
+int
+available_features_from_xml_string (struct gdb_feature_set *feature_set,
+				    const char *text, xml_fetch_another fetcher,
+				    void *fetcher_baton,
+				    int nested)
+{
+  XML_Parser parser;
+  struct xml_feature_parse_data *data;
+  struct cleanup *back_to;
+  char *expanded_text;
+  int ret;
+  union
+  {
+    /* We use a union to represent the checksum in order to guarantee
+       sufficient alignment.  */
+    uint32_t words[5];
+    unsigned char bytes[20];
+  } sha1sum;
+
+  /* Expand all XInclude directives.  */
+  ret = xml_process_xincludes (&expanded_text, text, fetcher, fetcher_baton,
+			       0);
+  if (ret != 0)
+    return -1;
+
+  /* Save the checksum.  */
+  sha1_buffer (expanded_text, strlen (expanded_text), sha1sum.bytes);
+  memcpy (feature_set->checksum, sha1sum.bytes, 20);
+
+  parser = XML_ParserCreateNS (NULL, '!');
+  if (parser == NULL)
+    return -1;
+  back_to = make_cleanup (xml_parser_cleanup, parser);
+
+  data = XCALLOC (1, struct xml_feature_parse_data);
+  XML_SetUserData (parser, data);
+
+  data->obstack = feature_set->obstack;
+  data->state = XCALLOC (1, struct xml_state_stack);
+  data->state->phase = PHASE_TOP;
+  data->state->u.top.nested = nested;
+
+  XML_SetElementHandler (parser, xml_feature_start_element,
+			 xml_feature_end_element);
+
+  XML_SetParamEntityParsing (parser,
+			     XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE);
+  XML_SetExternalEntityRefHandler (parser, xml_fetch_external_entity);
+
+  /* Even if no DTD is provided, use the built-in DTD anyway.  */
+  XML_UseForeignDTD (parser, XML_TRUE);
+
+  if (XML_Parse (parser, expanded_text, strlen (expanded_text), 1)
+      != XML_STATUS_OK)
+    {
+      enum XML_Error err = XML_GetErrorCode (parser);
+
+      warning (_("XML parsing error: %s"), XML_ErrorString (err));
+
+      do_cleanups (back_to);
+      return -1;
+    }
+
+  if (nested)
+    feature_set->features = data->seen_features;
+  else
+    feature_set->features = data->target_features;
+
+  /* TODO: If data->unhandled, warn?  */
+  /* TODO: Can other errors be fatal?  */
+  /* TODO: Should target_features == NULL be an error?  */
+
+  do_cleanups (back_to);
+
+  return 0;
+}
+
+static void
+do_cleanup_fclose (void *file)
+{
+  fclose (file);
+}
+
+static char *
+fetch_available_features_from_file (const char *filename, void *base_)
+{
+  const char *base = base_;
+  FILE *file;
+  struct cleanup *back_to;
+  char *text;
+  size_t len, offset;
+
+  if (base && *base)
+    {
+      char *fullname = concat (base, "/", filename, NULL);
+      if (fullname == NULL)
+	nomem (0);
+      file = fopen (fullname, FOPEN_RT);
+      xfree (fullname);
+    }
+  else
+    file = fopen (filename, FOPEN_RT);
+
+  if (file == NULL)
+    return NULL;
+  back_to = make_cleanup (do_cleanup_fclose, file);
+
+  /* Read in the whole file.  */
+  len = 4096;
+  offset = 0;
+  text = xmalloc (len);
+  make_cleanup (free_current_contents, &text);
+  while (1)
+    {
+      size_t bytes_read;
+
+      bytes_read = fread (text + offset, 1, len - offset, file);
+      if (ferror (file))
+	{
+	  warning (_("Could not read from \"%s\""), filename);
+	  do_cleanups (back_to);
+	  return NULL;
+	}
+
+      if (feof (file))
+	break;
+
+      offset += bytes_read;
+      len += len;
+      text = xrealloc (text, len);
+    }
+
+  fclose (file);
+  discard_cleanups (back_to);
+
+  return text;
+}
+
+int
+available_features_from_xml_file (struct gdb_feature_set *feature_set,
+				  const char *filename)
+{
+  struct cleanup *back_to = make_cleanup (null_cleanup, NULL);
+  const char *p;
+  char *dirname, *text;
+
+  text = fetch_available_features_from_file (filename, NULL);
+  if (text == NULL)
+    return -1;
+
+  /* Simple, portable version of dirname that does not modify its
+     argument.  */
+  p = lbasename (filename);
+  while (p > filename && IS_DIR_SEPARATOR (p[-1]))
+    --p;
+  if (p > filename)
+    {
+      dirname = xmalloc (p - filename + 1);
+      memcpy (dirname, filename, p - filename);
+      dirname[p - filename] = '\0';
+      make_cleanup (xfree, dirname);
+    }
+  else
+    dirname = NULL;
+
+  available_features_from_xml_string (feature_set, text,
+				      fetch_available_features_from_file,
+				      dirname, 0);
+
+  /* FIXME: We ignored the return value!  */
+
+  do_cleanups (back_to);
+
+  return 0;
+}
+
+/* For debugging.  */
+
+int
+try_available_features_from_xml_file (const char *filename)
+{
+  struct gdb_feature_set feature_set;
+  struct obstack obstack;
+  int ret;
+
+  obstack_init (&obstack);
+  feature_set.obstack = &obstack;
+  ret = available_features_from_xml_file (&feature_set, filename);
+  obstack_free (&obstack, NULL);
+
+  return ret;
+}
+
+/* XInclude processing.  This is done as a separate step from actually
+   parsing the document, so that we can produce a single combined XML
+   document to hand to a front end (and to simplify comparing two
+   documents).  The DTD is also processed in this stage, and default
+   values for attributes are filled in.  */
+
+struct xml_xinclude_parse_data
+{
+  /* The obstack to build the output in.  */
+  struct obstack obstack;
+
+  /* The current parser.  */
+  XML_Parser parser;
+
+  /* The external DTD subset, if one has been loaded.  */
+  char *external_dtd;
+
+  /* A count indicating whether we are in an element whose
+     children should not be copied to the output, and if so,
+     how deep we are nested.  This is used for any (unexpected)
+     children of XInclude directives, and for the DTD.  */
+  int skip_depth;
+
+  /* A function to call to obtain additional features, and its
+     baton.  */
+  xml_fetch_another fetcher;
+  void *fetcher_baton;
+
+  /* Rough count of unrecognized or invalid items found while
+     processing.  These are non-fatal; however, some data from the
+     input has been skipped.  */
+  int unhandled;
+};
+
+static void
+xml_xinclude_start_xinclude (struct xml_xinclude_parse_data *data,
+			     const XML_Char **attrs)
+{
+  struct cleanup *back_to;
+  char *text, *output;
+  int ret;
+  const char *href, **p;
+
+  href = NULL;
+  for (p = attrs; *p; p += 2)
+    {
+      const char *name = p[0], *val = p[1];
+
+      if (strcmp (name, "href") == 0)
+	href = val;
+      else
+	data->unhandled++;
+    }
+
+  if (href == NULL || data->fetcher == NULL)
+    {
+      data->unhandled++;
+      return;
+    }
+
+  text = data->fetcher (href, data->fetcher_baton);
+  if (text == NULL)
+    {
+      data->unhandled++;
+      return;
+    }
+
+  back_to = make_cleanup (xfree, text);
+
+  ret = xml_process_xincludes (&output, text,
+			       data->fetcher, data->fetcher_baton,
+			       1);
+
+  if (ret == 0)
+    obstack_grow (&data->obstack, output, strlen (output));
+  else
+    /* Something went wrong parsing the document.  */
+    data->unhandled++;
+
+  do_cleanups (back_to);
+}
+
+/* TODO: We output the doctype and <?xml> declaration for the first
+   document unchanged, if present, and discard those for included
+   documents.  Should we always generate doctype and version
+   information?  Never?  Should we include the external DTD subset
+   in the output document?
+
+   Issues to consider:
+   - We can not simply include the external DTD subset in the document
+   as an internal subset, because <!IGNORE> and <!INCLUDE> are valid
+   only in external subsets.  We may ignore this...
+   - Passing through the outer <?xml> declaration is incorrect because
+   we generate UTF-8, not whatever the input encoding was.
+   - If we do not pass the DTD into the output, default values will not
+   be filled in.  */
+
+static void XMLCALL
+xml_xinclude_start_element (void *data_, const XML_Char *name,
+			    const XML_Char **attrs)
+{
+  struct xml_xinclude_parse_data *data = data_;
+
+  /* If we are already skipping, keep on going.  */
+  if (data->skip_depth)
+    {
+      data->skip_depth++;
+      return;
+    }
+
+  if (strcmp (name, "http://www.w3.org/2001/XInclude!include") == 0)
+    {
+      xml_xinclude_start_xinclude (data, attrs);
+
+      /* Skip any children of this element (and its end).  */
+      data->skip_depth = 1;
+    }
+  else
+    XML_DefaultCurrent (data->parser);
+}
+
+static void XMLCALL
+xml_xinclude_end_element (void *data_, const XML_Char *name)
+{
+  struct xml_xinclude_parse_data *data = data_;
+
+  /* If we are skipping, update the depth.  */
+  if (data->skip_depth)
+    {
+      data->skip_depth--;
+      return;
+    }
+
+  /* Otherwise just print it out.  If this is the "end" of an empty element,
+     we don't need to do anything special - the default handler will get
+     called with LEN == 0.  */
+  XML_DefaultCurrent (data->parser);
+}
+
+static void XMLCALL
+xml_xinclude_default (void *data_, const XML_Char *s, int len)
+{
+  struct xml_xinclude_parse_data *data = data_;
+
+  /* If we are inside of e.g. xi:include or the DTD, don't save this
+     string.  */
+  if (data->skip_depth)
+    return;
+
+  obstack_grow (&data->obstack, s, len);
+}
+
+static void XMLCALL
+xml_xinclude_start_doctype (void *data_, const XML_Char *doctypeName,
+			    const XML_Char *sysid, const XML_Char *pubid,
+			    int has_internal_subset)
+{
+  struct xml_xinclude_parse_data *data = data_;
+
+  /* Don't print out the doctype, or the contents of the DTD internal
+     subset, if any.  */
+  data->skip_depth++;
+}
+
+static void XMLCALL
+xml_xinclude_end_doctype (void *data_)
+{
+  struct xml_xinclude_parse_data *data = data_;
+
+  data->skip_depth--;
+}
+
+static void XMLCALL
+xml_xinclude_xml_decl (void *data_, const XML_Char *version,
+		       const XML_Char *encoding, int standalone)
+{
+  /* Do nothing - this prevents the default handler from being called.  */
+}
+
+static void
+xml_xinclude_parser_cleanup (void *parser)
+{
+  struct xml_xinclude_parse_data *data;
+
+  data = XML_GetUserData (parser);
+  if (data)
+    {
+      obstack_free (&data->obstack, NULL);
+
+      if (data->external_dtd)
+	xfree (data->external_dtd);
+
+      xfree (data);
+    }
+
+  XML_ParserFree (parser);
+}
+
+/* FIXME: Error check more XML_* calls.  */
+
+int
+xml_process_xincludes (char **output_p, const char *text,
+		       xml_fetch_another fetcher, void *fetcher_baton,
+		       int nested)
+{
+  XML_Parser parser;
+  struct xml_xinclude_parse_data *data;
+  struct cleanup *back_to;
+
+  parser = XML_ParserCreateNS (NULL, '!');
+  if (parser == NULL)
+    return -1;
+  back_to = make_cleanup (xml_xinclude_parser_cleanup, parser);
+
+  data = XCALLOC (1, struct xml_xinclude_parse_data);
+  XML_SetUserData (parser, data);
+
+  obstack_init (&data->obstack);
+
+  data->parser = parser;
+  data->fetcher = fetcher;
+  data->fetcher_baton = fetcher_baton;
+
+  XML_SetElementHandler (parser, xml_xinclude_start_element,
+			 xml_xinclude_end_element);
+  XML_SetDefaultHandler (parser, xml_xinclude_default);
+
+  /* Always discard the XML version declarations; the only important
+     thing this provides is encoding, and our result will have been
+     converted to UTF-8.  */
+  XML_SetXmlDeclHandler (parser, xml_xinclude_xml_decl);
+
+  if (nested)
+    /* Discard the doctype for included documents.  */
+    XML_SetDoctypeDeclHandler (parser, xml_xinclude_start_doctype,
+			       xml_xinclude_end_doctype);
+
+  XML_SetParamEntityParsing (parser,
+			     XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE);
+  XML_SetExternalEntityRefHandler (parser, xml_fetch_external_entity);
+
+  /* Even if no DTD is provided, use the built-in DTD anyway.  */
+  XML_UseForeignDTD (parser, XML_TRUE);
+
+  if (XML_Parse (parser, text, strlen (text), 1) != XML_STATUS_OK)
+    {
+      enum XML_Error err = XML_GetErrorCode (parser);
+
+      warning (_("XML parsing error: %s"), XML_ErrorString (err));
+
+      do_cleanups (back_to);
+      return -1;
+    }
+
+  /* TODO: If data->unhandled, warn?  */
+  /* TODO: Can other errors be fatal?  */
+
+  obstack_1grow (&data->obstack, '\0');
+  *output_p = xstrdup (obstack_finish (&data->obstack));
+
+  do_cleanups (back_to);
+
+  return 0;
+}
+
+int
+xml_xinclude_from_file (char **output_p, const char *filename)
+{
+  struct cleanup *back_to = make_cleanup (null_cleanup, NULL);
+  const char *p;
+  char *dirname, *text;
+  int ret;
+
+  text = fetch_available_features_from_file (filename, NULL);
+  if (text == NULL)
+    return -1;
+
+  /* Simple, portable version of dirname that does not modify its
+     argument.  */
+  p = lbasename (filename);
+  while (p > filename && IS_DIR_SEPARATOR (p[-1]))
+    --p;
+  if (p > filename)
+    {
+      dirname = xmalloc (p - filename + 1);
+      memcpy (dirname, filename, p - filename);
+      dirname[p - filename] = '\0';
+      make_cleanup (xfree, dirname);
+    }
+  else
+    dirname = NULL;
+
+  ret = xml_process_xincludes (output_p, text,
+			       fetch_available_features_from_file,
+			       dirname, 0);
+
+  do_cleanups (back_to);
+  return ret;
+}
+
+/* For debugging.  */
+
+int
+try_xml_xinclude_from_xml_file (const char *filename)
+{
+  char *output;
+  int ret;
+
+  ret = xml_xinclude_from_file (&output, filename);
+
+  if (ret == 0)
+    printf_unfiltered ("%s", output);
+
+  return ret;
+}
+
+/* Return the XML corresponding to the given filename, if it
+   was compiled in to GDB, and NULL otherwise.  */
+
+const char *
+fetch_xml_builtin (const char *name)
+{
+  const char *(*p)[2];
+
+  for (p = xml_builtin; (*p)[0]; p++)
+    if (strcmp ((*p)[0], name) == 0)
+      return (*p)[1];
+
+  return NULL;
+}
diff --git a/gdb/procfs.c b/gdb/procfs.c
index 1fd45a3..143a639 100644
--- a/gdb/procfs.c
+++ b/gdb/procfs.c
@@ -6122,7 +6122,8 @@
       note_data = thread_args.note_data;
     }
 
-  auxv_len = target_auxv_read (&current_target, &auxv);
+  auxv_len = target_read_whole (&current_target, TARGET_OBJECT_AUXV, NULL,
+				&auxv);
   if (auxv_len > 0)
     {
       note_data = elfcore_write_note (obfd, note_data, note_size,
diff --git a/gdb/remote.c b/gdb/remote.c
index 5dc7ab4..b078e6c 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -45,6 +45,7 @@
 #include "solib.h"
 #include "cli/cli-decode.h"
 #include "cli/cli-setshow.h"
+#include "available.h"
 
 #include <ctype.h>
 #include <sys/time.h>
@@ -188,8 +189,21 @@
 
 static void update_packet_config (struct packet_config *config);
 
+static void set_remote_protocol_packet_cmd (char *args, int from_tty,
+					    struct cmd_list_element *c);
+
+static void show_remote_protocol_packet_cmd (struct ui_file *file,
+					     int from_tty,
+					     struct cmd_list_element *c,
+					     const char *value);
+
 void _initialize_remote (void);
 
+/* For "set remote" and "show remote".  */
+
+static struct cmd_list_element *remote_set_cmdlist;
+static struct cmd_list_element *remote_show_cmdlist;
+
 /* 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.
@@ -214,7 +228,7 @@
   long sizeof_g_packet;
 
   /* Description of the remote protocol registers indexed by REGNUM
-     (making an array of NUM_REGS + NUM_PSEUDO_REGS in size).  */
+     (making an array NUM_REGS in size).  */
   struct packet_reg *regs;
 
   /* This is the size (in chars) of the first response to the ``g''
@@ -228,6 +242,10 @@
   /* 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;
+
+  /* This flag is set if we negotiated packet size explicitly (and
+     can bypass various heuristics).  */
+  int explicit_packet_size;
 };
 
 
@@ -240,31 +258,60 @@
   return gdbarch_data (current_gdbarch, remote_gdbarch_data_handle);
 }
 
+static int
+compare_pnums (const void *lhs_, const void *rhs_)
+{
+  const struct packet_reg * const *lhs = lhs_;
+  const struct packet_reg * const *rhs = rhs_;
+
+  if ((*lhs)->pnum < (*rhs)->pnum)
+    return -1;
+  else if ((*lhs)->pnum == (*rhs)->pnum)
+    return 0;
+  else
+    return 1;
+}
+
 static void *
 init_remote_state (struct gdbarch *gdbarch)
 {
-  int regnum;
+  int regnum, num_remote_regs, offset;
   struct remote_state *rs = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct remote_state);
+  struct packet_reg **remote_regs;
 
-  rs->sizeof_g_packet = 0;
-
-  /* Assume a 1:1 regnum<->pnum table.  */
-  rs->regs = GDBARCH_OBSTACK_CALLOC (gdbarch, NUM_REGS + NUM_PSEUDO_REGS,
-				     struct packet_reg);
-  for (regnum = 0; regnum < NUM_REGS + NUM_PSEUDO_REGS; regnum++)
+  /* Assume a 1:1 regnum<->pnum table unless the available registers
+     interface informs us otherwise.  */
+  rs->regs = GDBARCH_OBSTACK_CALLOC (gdbarch, NUM_REGS, struct packet_reg);
+  for (regnum = 0; regnum < NUM_REGS; regnum++)
     {
       struct packet_reg *r = &rs->regs[regnum];
-      r->pnum = regnum;
+      r->pnum = available_register_target_regnum (gdbarch, regnum);
       r->regnum = regnum;
-      r->offset = DEPRECATED_REGISTER_BYTE (regnum);
-      r->in_g_packet = (regnum < NUM_REGS);
-      /* ...name = REGISTER_NAME (regnum); */
-
-      /* Compute packet size by accumulating the size of all registers.  */
-      if (regnum < NUM_REGS)
-	rs->sizeof_g_packet += register_size (current_gdbarch, regnum);
     }
 
+  /* Define the g/G packet format as the contents of each register
+     with a remote protocol number, in order of ascending protocol
+     number.  */
+
+  remote_regs = alloca (NUM_REGS * sizeof (struct packet_reg *));
+  for (num_remote_regs = 0, regnum = 0; regnum < NUM_REGS; regnum++)
+    if (rs->regs[regnum].pnum != -1)
+      remote_regs[num_remote_regs++] = &rs->regs[regnum];
+
+  qsort (remote_regs, num_remote_regs, sizeof (struct packet_reg *),
+	 compare_pnums);
+
+  for (regnum = 0, offset = 0; regnum < num_remote_regs; regnum++)
+    {
+      remote_regs[regnum]->in_g_packet = 1;
+      remote_regs[regnum]->offset = offset;
+      offset += register_size (current_gdbarch, remote_regs[regnum]->regnum);
+    }
+
+  /* Record the maximum possible size of the g packet - it may turn out
+     to be smaller.  */
+  rs->sizeof_g_packet = offset;
+
   /* 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
@@ -292,7 +339,7 @@
 static struct packet_reg *
 packet_reg_from_regnum (struct remote_state *rs, long regnum)
 {
-  if (regnum < 0 && regnum >= NUM_REGS + NUM_PSEUDO_REGS)
+  if (regnum < 0 && regnum >= NUM_REGS)
     return NULL;
   else
     {
@@ -306,7 +353,7 @@
 packet_reg_from_pnum (struct remote_state *rs, LONGEST pnum)
 {
   int i;
-  for (i = 0; i < NUM_REGS + NUM_PSEUDO_REGS; i++)
+  for (i = 0; i < NUM_REGS; i++)
     {
       struct packet_reg *r = &rs->regs[i];
       if (r->pnum == pnum)
@@ -427,10 +474,13 @@
       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);
+
+      /* Limit it to the size of the targets ``g'' response unless we have
+	 permission from the stub to use a larger packet size.  */
+      if (!rs->explicit_packet_size
+	  && 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;
@@ -566,6 +616,7 @@
     char *title;
     enum auto_boolean detect;
     enum packet_support support;
+    int must_be_reported;
   };
 
 /* Analyze a packet's return value and update the packet config
@@ -629,11 +680,8 @@
 add_packet_config_cmd (struct packet_config *config,
 		       char *name,
 		       char *title,
-		       cmd_sfunc_ftype *set_func,
-		       show_value_ftype *show_func,
-		       struct cmd_list_element **set_remote_list,
-		       struct cmd_list_element **show_remote_list,
-		       int legacy)
+		       int legacy,
+		       int must_be_reported)
 {
   char *set_doc;
   char *show_doc;
@@ -643,6 +691,7 @@
   config->title = title;
   config->detect = AUTO_BOOLEAN_AUTO;
   config->support = PACKET_SUPPORT_UNKNOWN;
+  config->must_be_reported = must_be_reported;
   set_doc = xstrprintf ("Set use of remote protocol `%s' (%s) packet",
 			name, title);
   show_doc = xstrprintf ("Show current use of remote protocol `%s' (%s) packet",
@@ -651,17 +700,18 @@
   cmd_name = xstrprintf ("%s-packet", title);
   add_setshow_auto_boolean_cmd (cmd_name, class_obscure,
 				&config->detect, set_doc, show_doc, NULL, /* help_doc */
-				set_func, show_func,
-				set_remote_list, show_remote_list);
+				set_remote_protocol_packet_cmd,
+				show_remote_protocol_packet_cmd,
+				&remote_set_cmdlist, &remote_show_cmdlist);
   /* set/show remote NAME-packet {auto,on,off} -- legacy.  */
   if (legacy)
     {
       char *legacy_name;
       legacy_name = xstrprintf ("%s-packet", name);
       add_alias_cmd (legacy_name, cmd_name, class_obscure, 0,
-		     set_remote_list);
+		     &remote_set_cmdlist);
       add_alias_cmd (legacy_name, cmd_name, class_obscure, 0,
-		     show_remote_list);
+		     &remote_show_cmdlist);
     }
 }
 
@@ -732,6 +782,7 @@
 enum {
   PACKET_vCont = 0,
   PACKET_X,
+  PACKET_qOffsets,
   PACKET_qSymbol,
   PACKET_P,
   PACKET_p,
@@ -741,6 +792,7 @@
   PACKET_Z3,
   PACKET_Z4,
   PACKET_qPart_auxv,
+  PACKET_qPart_features,
   PACKET_qGetTLSAddr,
   PACKET_MAX
 };
@@ -1796,14 +1848,20 @@
   CORE_ADDR text_addr, data_addr, bss_addr;
   struct section_offsets *offs;
 
+  if (remote_protocol_packets[PACKET_qOffsets].support == PACKET_DISABLE)
+    return;
+
   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')
+  switch (packet_ok (buf, &remote_protocol_packets[PACKET_qOffsets]))
     {
+    case PACKET_OK:
+      break;
+    case PACKET_UNKNOWN:
+      return;			/* Return silently.  Stub doesn't support
+				   this command.  */
+    case PACKET_ERROR:
       warning (_("Remote failure reply: %s"), buf);
       return;
     }
@@ -2003,6 +2061,108 @@
 }
 
 static void
+remote_query_packet_info (void)
+{
+  struct remote_state *rs = get_remote_state ();
+  char *reply, *next;
+  int i;
+
+  reply = alloca (rs->remote_packet_size);
+
+  putpkt ("qPacketInfo");
+  getpkt (reply, rs->remote_packet_size, 0);
+
+  next = reply;
+  while (*next)
+    {
+      enum packet_support is_supported;
+      char *p, *end, *name_end;
+
+      p = next;
+      end = strchr (p, ';');
+      if (end == NULL)
+	{
+	  end = p + strlen (p);
+	  next = end;
+	}
+      else
+	{
+	  if (end == p)
+	    {
+	      warning (_("empty item in \"qPacketInfo\" response"));
+	      continue;
+	    }
+
+	  *end = '\0';
+	  next = end + 1;
+	}
+
+      name_end = strchr (p, '=');
+      if (name_end)
+	{
+	  /* This is a name=value entry.  */
+	  char *value;
+
+	  value = name_end + 1;
+	  *name_end = '\0';
+
+	  if (strcmp (p, "PacketSize") == 0)
+	    {
+	      int packet_size;
+	      char *value_end;
+
+	      packet_size = strtol (value, &value_end, 16);
+	      if (*value != '\0' && *value_end == '\0')
+		{
+		  /* MERGE WARNING: This needs the infinite length
+		     incoming packet support, which in turn needs us
+		     to adjust rs->buf_size here.  */
+		  if (packet_size > MAX_REMOTE_PACKET_SIZE)
+		    {
+		      warning (_("limiting remote suggested packet size (%d bytes) to %d"),
+			       packet_size, MAX_REMOTE_PACKET_SIZE);
+		      packet_size = MAX_REMOTE_PACKET_SIZE;
+		    }
+		  rs->remote_packet_size = packet_size;
+		  rs->explicit_packet_size = 1;
+
+		  continue;
+		}
+	    }
+
+	  /* Should we even warn about this?  For testing, at least, yes.  */
+	  warning (_("unrecognized item \"%s=%s\" in \"qPacketInfo\" response"),
+		   p, value);
+	  continue;
+	}
+
+      if (end[-1] != '+' && end[-1] != '-')
+	{
+	  warning (_("unrecognized item \"%s\" in \"qPacketInfo\" response"), p);
+	  continue;
+	}
+
+      is_supported = (end[-1] == '+') ? PACKET_ENABLE : PACKET_DISABLE;
+      end[-1] = '\0';
+
+      for (i = 0; i < PACKET_MAX; i++)
+	if (strcmp (remote_protocol_packets[i].name, p) == 0)
+	  {
+	    if (remote_protocol_packets[i].support == PACKET_SUPPORT_UNKNOWN)
+	      remote_protocol_packets[i].support = is_supported;
+	    break;
+	  }
+    }
+
+  /* Default some unmentioned packets to unsupported.  */
+  for (i = 0; i < PACKET_MAX; i++)
+    if (remote_protocol_packets[i].must_be_reported
+	&& remote_protocol_packets[i].support == PACKET_SUPPORT_UNKNOWN)
+      remote_protocol_packets[i].support = PACKET_DISABLE;
+}
+
+
+static void
 remote_open_1 (char *name, int from_tty, struct target_ops *target,
 	       int extended_p, int async_p)
 {
@@ -2064,6 +2224,11 @@
   use_threadinfo_query = 1;
   use_threadextra_query = 1;
 
+  /* The first packet we send to the target is the optional "supported
+     packets" request.  If the target can answer this, it will tell us
+     which later probes to skip.  */
+  remote_query_packet_info ();
+
   /* 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
@@ -2088,6 +2253,14 @@
       wait_forever_enabled_p = 0;
     }
 
+  /* FIXME: This is a hack.  Default to an architecture with no
+     available features here, and set the real one further down.
+     Ideally, we ought to set the real architecture here (and
+     also in remote_create_inferior maybe?) but not redo it
+     in post_inferior_created below.  That will take some rearranging
+     that I don't have time for right now.  */
+  arch_set_available_features (NULL);
+
   /* First delete any symbols previously loaded from shared libraries.  */
   no_shared_libraries (NULL, 0);
 
@@ -3031,112 +3204,116 @@
   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.  */
+/* Fetch a single register using a 'p' packet.  */
 
 static int
-fetch_register_using_p (int regnum)
+fetch_register_using_p (struct packet_reg *reg)
 {
   struct remote_state *rs = get_remote_state ();
   char *buf = alloca (rs->remote_packet_size), *p;
   char regp[MAX_REGISTER_SIZE];
   int i;
 
+  if (remote_protocol_packets[PACKET_p].support == PACKET_DISABLE)
+    return 0;
+
+  if (reg->pnum == -1)
+    return 0;
+
   p = buf;
   *p++ = 'p';
-  p += hexnumstr (p, regnum);
+  p += hexnumstr (p, reg->pnum);
   *p++ = '\0';
   remote_send (buf, rs->remote_packet_size);
 
-  /* If the stub didn't recognize the packet, or if we got an error,
-     tell our caller.  */
-  if (buf[0] == '\0' || buf[0] == 'E')
-    return 0;
+  switch (packet_ok (buf, &remote_protocol_packets[PACKET_p]))
+    {
+    case PACKET_OK:
+      break;
+    case PACKET_UNKNOWN:
+      return 0;
+    case PACKET_ERROR:
+      error (_("Could not fetch register \"%s\""),
+	     gdbarch_register_name (current_gdbarch, reg->regnum));
+    }
 
-  /* If this register is unfetchable, tell the regcache.  */
   if (buf[0] == 'x')
     {
-      regcache_raw_supply (current_regcache, regnum, NULL);
-      set_register_cached (regnum, -1);
+      regcache_raw_supply (current_regcache, reg->regnum, NULL);
+      set_register_cached (reg->regnum, -1);
       return 1;
     }
 
-  /* Otherwise, parse and supply the value.  */
   p = buf;
   i = 0;
   while (p[0] != 0)
     {
       if (p[1] == 0)
-        {
-          error (_("fetch_register_using_p: early buf termination"));
-          return 0;
-        }
-
+	error (_("fetch_register_using_p: early buf termination"));
       regp[i++] = fromhex (p[0]) * 16 + fromhex (p[1]);
       p += 2;
     }
-  regcache_raw_supply (current_regcache, regnum, regp);
+  regcache_raw_supply (current_regcache, reg->regnum, regp);
   return 1;
 }
 
+/* Fetch the registers included in the target's 'g' packet.  */
+
 static void
-remote_fetch_registers (int regnum)
+fetch_registers_using_g (void)
 {
   struct remote_state *rs = get_remote_state ();
   char *buf = alloca (rs->remote_packet_size);
-  int i;
+  int i, buf_len;
   char *p;
-  char *regs = alloca (rs->sizeof_g_packet);
+  char *regs;
 
   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."));
-    }
-      switch (remote_protocol_packets[PACKET_p].support)
-	{
-	case PACKET_DISABLE:
-	  break;
-	case PACKET_ENABLE:
-	  if (fetch_register_using_p (regnum))
-	    return;
-	  else
-	    error (_("Protocol error: p packet not recognized by stub"));
-	case PACKET_SUPPORT_UNKNOWN:
-	  if (fetch_register_using_p (regnum))
-	    {
-	      /* The stub recognized the 'p' packet.  Remember this.  */
-	      remote_protocol_packets[PACKET_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_packets[PACKET_p].support = PACKET_DISABLE;
-	      break;
-	    }
-	}
-
   sprintf (buf, "g");
   remote_send (buf, rs->remote_packet_size);
 
-  /* Save the size of the packet sent to us by the target.  Its used
+  buf_len = strlen (buf);
+
+  /* Sanity check the received packet.  */
+  if (buf_len % 2 != 0)
+    error (_("Remote 'g' packet reply is of odd length: %s"), buf);
+  if (REGISTER_BYTES_OK_P () && !REGISTER_BYTES_OK (buf_len / 2))
+    error (_("Remote 'g' packet reply is too short: %s"), buf);
+
+  /* Save the size of the packet sent to us by the target.  It is 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);
+  if (rs->actual_register_packet_size == 0)
+    rs->actual_register_packet_size = buf_len;
+
+  /* If this is smaller than we guessed the 'g' packet would be,
+     update our records.  A 'g' reply that doesn't include a register's
+     value implies either that the register is not available, or that
+     the 'p' packet must be used.  */
+  /* FIXME: Allow bigger, too.  We have no choice.  We might not have the right
+     architecture selected, because we haven't yet sent qPart:features, and
+     in turn that means we might clobber the no-features architecture
+     with the g packet from a feature-ful architecture.  Really, sending a
+     g packet at all before we know the target features is asking for
+     trouble.  Order of initialization needs to be changed.  */
+  if (buf_len != 2 * rs->sizeof_g_packet)
+    {
+      rs->sizeof_g_packet = buf_len / 2;
+
+      for (i = 0; i < NUM_REGS; i++)
+	{
+	  if (rs->regs[i].pnum == -1)
+	    continue;
+
+	  if (rs->regs[i].offset >= rs->sizeof_g_packet)
+	    rs->regs[i].in_g_packet = 0;
+	  else
+	    rs->regs[i].in_g_packet = 1;
+	}
+    }
+
+  regs = alloca (rs->sizeof_g_packet);
 
   /* Unimplemented registers read as all bits zero.  */
   memset (regs, 0, rs->sizeof_g_packet);
@@ -3162,15 +3339,11 @@
   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] == 0 || p[1] == 0)
+	/* This shouldn't happen - we adjusted sizeof_g_packet above.  */
+	internal_error (__FILE__, __LINE__,
+			"unexpected end of 'g' packet reply");
+
       if (p[0] == 'x' && p[1] == 'x')
 	regs[i] = 0;		/* 'x' */
       else
@@ -3178,28 +3351,17 @@
       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++)
+    for (i = 0; i < NUM_REGS; i++)
       {
 	struct packet_reg *r = &rs->regs[i];
 	if (r->in_g_packet)
 	  {
 	    if (r->offset * 2 >= strlen (buf))
-	      /* A short packet that didn't include the register's
-                 value, this implies that the register is zero (and
-                 not that the register is unavailable).  Supply that
-                 zero value.  */
-	      regcache_raw_supply (current_regcache, r->regnum, NULL);
+	      /* This shouldn't happen - we adjusted in_g_packet above.  */
+	      internal_error (__FILE__, __LINE__,
+			      "unexpected end of 'g' packet reply");
 	    else if (buf[r->offset * 2] == 'x')
 	      {
 		gdb_assert (r->offset * 2 < strlen (buf));
@@ -3216,6 +3378,52 @@
   }
 }
 
+static void
+remote_fetch_registers (int regnum)
+{
+  struct remote_state *rs = get_remote_state ();
+  int i;
+
+  set_thread (PIDGET (inferior_ptid), 1);
+
+  if (regnum >= 0)
+    {
+      struct packet_reg *reg = packet_reg_from_regnum (rs, regnum);
+      gdb_assert (reg != NULL);
+
+      /* If this register might be in the 'g' packet, try that first -
+	 we are likely to read more than one register.  If this is the
+	 first 'g' packet, we might be overly optimistic about its
+	 contents, so fall back to 'p'.  */
+      if (reg->in_g_packet)
+	{
+	  fetch_registers_using_g ();
+	  if (reg->in_g_packet)
+	    return;
+	}
+
+      if (fetch_register_using_p (reg))
+	return;
+
+      /* This register is not available.  */
+      regcache_raw_supply (current_regcache, reg->regnum, NULL);
+      set_register_cached (reg->regnum, -1);
+
+      return;
+    }
+
+  fetch_registers_using_g ();
+
+  for (i = 0; i < NUM_REGS; i++)
+    if (!rs->regs[i].in_g_packet)
+      if (!fetch_register_using_p (&rs->regs[i]))
+	{
+	  /* This register is not available.  */
+	  regcache_raw_supply (current_regcache, i, NULL);
+	  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.  */
@@ -3246,74 +3454,58 @@
    packet was not recognized.  */
 
 static int
-store_register_using_P (int regnum)
+store_register_using_P (struct packet_reg *reg)
 {
   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);
   gdb_byte regp[MAX_REGISTER_SIZE];
   char *p;
 
+  if (remote_protocol_packets[PACKET_P].support == PACKET_DISABLE)
+    return 0;
+
+  if (reg->pnum == -1)
+    return 0;
+
   xsnprintf (buf, rs->remote_packet_size, "P%s=", phex_nz (reg->pnum, 0));
   p = buf + strlen (buf);
   regcache_raw_collect (current_regcache, reg->regnum, regp);
   bin2hex (regp, p, register_size (current_gdbarch, reg->regnum));
   remote_send (buf, rs->remote_packet_size);
 
-  return buf[0] != '\0';
+  switch (packet_ok (buf, &remote_protocol_packets[PACKET_P]))
+    {
+    case PACKET_OK:
+      return 1;
+    case PACKET_ERROR:
+      error (_("Could not write register \"%s\""),
+	     gdbarch_register_name (current_gdbarch, reg->regnum));
+    case PACKET_UNKNOWN:
+      return 0;
+    default:
+      internal_error (__FILE__, __LINE__, _("Bad result from packet_ok"));
+    }
 }
 
-
 /* 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)
+store_registers_using_G ()
 {
   struct remote_state *rs = get_remote_state ();
   char *buf;
   gdb_byte *regs;
   char *p;
 
-  set_thread (PIDGET (inferior_ptid), 1);
-
-  if (regnum >= 0)
-    {
-      switch (remote_protocol_packets[PACKET_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_packets[PACKET_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_packets[PACKET_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, 0, rs->sizeof_g_packet);
-    for (i = 0; i < NUM_REGS + NUM_PSEUDO_REGS; i++)
+    for (i = 0; i < NUM_REGS; i++)
       {
 	struct packet_reg *r = &rs->regs[i];
 	if (r->in_g_packet)
@@ -3326,10 +3518,54 @@
   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_prepare_to_store insures that rs->sizeof_g_packet gets
+     updated.  */
+  bin2hex (regs, p, rs->sizeof_g_packet);
   remote_send (buf, rs->remote_packet_size);
 }
+
+/* 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 ();
+  int i;
+
+  set_thread (PIDGET (inferior_ptid), 1);
+
+  if (regnum >= 0)
+    {
+      struct packet_reg *reg = packet_reg_from_regnum (rs, regnum);
+      gdb_assert (reg != NULL);
+
+      /* Always prefer to store registers using the 'P' packet if
+	 possible; we often change only a small number of registers.
+         Sometimes we change a larger number; we'd need help from a
+	 higher layer to know to use 'G'.  */
+      if (store_register_using_P (reg))
+	return;
+
+      /* For now, don't complain if we have no way to write the
+	 register.  GDB loses track of unavailable registers too
+	 easily.  Some day, this may be an error.  We don't have
+	 any way to read the register, either... */
+      if (!reg->in_g_packet)
+	return;
+
+      store_registers_using_G ();
+      return;
+    }
+
+  store_registers_using_G ();
+
+  for (i = 0; i < NUM_REGS; i++)
+    if (!rs->regs[i].in_g_packet)
+      if (!store_register_using_P (&rs->regs[i]))
+	/* See above for why we do not issue an error here.  */
+	continue;
+}
 
 
 /* Return the number of hex digits in num.  */
@@ -4763,6 +4999,49 @@
     printf_filtered (_("No loaded section named '%s'.\n"), args);
 }
 
+/* Read OBJECT_NAME/ANNEX from the remote target using a qPart packet.
+   Data at OFFSET, of up to LEN bytes, is read into READBUF; the
+   number of bytes read is returned, or 0 for EOF, or -1 for error.
+   The number of bytes read may be less than LEN without indicating an
+   EOF.  PACKET is checked and updated to indicate whether the remote
+   target supports this object.  */
+
+static LONGEST
+remote_read_qpart (struct target_ops *ops, const char *object_name,
+		   const char *annex,
+		   gdb_byte *readbuf, ULONGEST offset, LONGEST len,
+		   struct packet_config *packet)
+{
+  struct remote_state *rs = get_remote_state ();
+  char *buf2 = alloca (rs->remote_packet_size);
+  unsigned int total = 0;
+  LONGEST i, n;
+
+  if (packet->support == PACKET_DISABLE)
+    return -1;
+
+  n = min ((rs->remote_packet_size - 2) / 2, len);
+  snprintf (buf2, rs->remote_packet_size, "qPart:%s:read:%s:%s,%s",
+	    object_name, annex ? annex : "",
+	    phex_nz (offset, sizeof offset),
+	    phex_nz (n, sizeof n));
+  i = putpkt (buf2);
+  if (i < 0)
+    return -1;
+
+  buf2[0] = '\0';
+  getpkt (buf2, rs->remote_packet_size, 0);
+  if (packet_ok (buf2, packet) != PACKET_OK)
+    return -1;
+
+  if (buf2[0] == 'O' && buf2[1] == 'K' && buf2[2] == '\0')
+    return 0;		/* Got EOF indicator.  */
+
+  /* Got some data.  */
+  i = hex2bin (buf2, readbuf, len);
+  return i;
+}
+
 static LONGEST
 remote_xfer_partial (struct target_ops *ops, enum target_object object,
 		     const char *annex, gdb_byte *readbuf,
@@ -4770,8 +5049,7 @@
 {
   struct remote_state *rs = get_remote_state ();
   int i;
-  char *buf2 = alloca (rs->remote_packet_size);
-  char *p2 = &buf2[0];
+  char *buf2, *p2;
   char query_type;
 
   /* Handle memory using remote_xfer_memory.  */
@@ -4815,39 +5093,13 @@
       break;
 
     case TARGET_OBJECT_AUXV:
-      if (remote_protocol_packets[PACKET_qPart_auxv].support != PACKET_DISABLE)
-	{
-	  unsigned int total = 0;
-	  while (len > 0)
-	    {
-	      LONGEST n = min ((rs->remote_packet_size - 2) / 2, len);
-	      snprintf (buf2, rs->remote_packet_size,
-			"qPart:auxv:read::%s,%s",
-			phex_nz (offset, sizeof offset),
-			phex_nz (n, sizeof n));
-	      i = putpkt (buf2);
-	      if (i < 0)
-		return total > 0 ? total : i;
-	      buf2[0] = '\0';
-	      getpkt (buf2, rs->remote_packet_size, 0);
-	      if (packet_ok (buf2, &remote_protocol_packets[PACKET_qPart_auxv])
-		  != PACKET_OK)
-		return total > 0 ? total : -1;
-	      if (buf2[0] == 'O' && buf2[1] == 'K' && buf2[2] == '\0')
-		break;		/* Got EOF indicator.  */
-	      /* Got some data.  */
-	      i = hex2bin (buf2, readbuf, len);
-	      if (i > 0)
-		{
-		  readbuf = (void *) ((char *) readbuf + i);
-		  offset += i;
-		  len -= i;
-		  total += i;
-		}
-	    }
-	  return total;
-	}
-      return -1;
+      gdb_assert (annex == NULL);
+      return remote_read_qpart (ops, "auxv", annex, readbuf, offset, len,
+				&remote_protocol_packets[PACKET_qPart_auxv]);
+
+    case TARGET_OBJECT_AVAILABLE_FEATURES:
+      return remote_read_qpart (ops, "features", annex, readbuf, offset, len,
+				&remote_protocol_packets[PACKET_qPart_features]);
 
     default:
       return -1;
@@ -4870,6 +5122,9 @@
   gdb_assert (annex != NULL);
   gdb_assert (readbuf != NULL);
 
+  buf2 = alloca (rs->remote_packet_size);
+  p2 = &buf2[0];
+
   *p2++ = 'q';
   *p2++ = query_type;
 
@@ -5221,6 +5476,7 @@
   remote_ops.to_xfer_partial = remote_xfer_partial;
   remote_ops.to_rcmd = remote_rcmd;
   remote_ops.to_get_thread_local_address = remote_get_thread_local_address;
+  remote_ops.to_available_features = available_features_from_target_object;
   remote_ops.to_stratum = process_stratum;
   remote_ops.to_has_all_memory = 1;
   remote_ops.to_has_memory = 1;
@@ -5346,6 +5602,8 @@
   remote_async_ops.to_stop = remote_stop;
   remote_async_ops.to_xfer_partial = remote_xfer_partial;
   remote_async_ops.to_rcmd = remote_rcmd;
+  remote_async_ops.to_available_features
+    = available_features_from_target_object;
   remote_async_ops.to_stratum = process_stratum;
   remote_async_ops.to_has_all_memory = 1;
   remote_async_ops.to_has_memory = 1;
@@ -5379,9 +5637,6 @@
   extended_async_remote_ops.to_mourn_inferior = extended_remote_mourn;
 }
 
-static struct cmd_list_element *remote_set_cmdlist;
-static struct cmd_list_element *remote_show_cmdlist;
-
 static void
 set_remote_cmd (char *args, int from_tty)
 {
@@ -5559,88 +5814,47 @@
 			   &setlist, &showlist);
 
   add_packet_config_cmd (&remote_protocol_packets[PACKET_X],
-			 "X", "binary-download",
-			 set_remote_protocol_packet_cmd,
-			 show_remote_protocol_packet_cmd,
-			 &remote_set_cmdlist, &remote_show_cmdlist,
-			 1);
+			 "X", "binary-download", 1, 0);
 
   add_packet_config_cmd (&remote_protocol_packets[PACKET_vCont],
-			 "vCont", "verbose-resume",
-			 set_remote_protocol_packet_cmd,
-			 show_remote_protocol_packet_cmd,
-			 &remote_set_cmdlist, &remote_show_cmdlist,
-			 0);
+			 "vCont", "verbose-resume", 0, 0);
+
+  add_packet_config_cmd (&remote_protocol_packets[PACKET_qOffsets],
+			 "qOffsets", "load-offsets", 0, 0);
 
   add_packet_config_cmd (&remote_protocol_packets[PACKET_qSymbol],
-			 "qSymbol", "symbol-lookup",
-			 set_remote_protocol_packet_cmd,
-			 show_remote_protocol_packet_cmd,
-			 &remote_set_cmdlist, &remote_show_cmdlist,
-			 0);
+			 "qSymbol", "symbol-lookup", 0, 0);
 
   add_packet_config_cmd (&remote_protocol_packets[PACKET_P],
-			 "P", "set-register",
-			 set_remote_protocol_packet_cmd,
-			 show_remote_protocol_packet_cmd,
-			 &remote_set_cmdlist, &remote_show_cmdlist,
-			 1);
+			 "P", "set-register", 1, 0);
 
   add_packet_config_cmd (&remote_protocol_packets[PACKET_p],
-			 "p", "fetch-register",
-			 set_remote_protocol_packet_cmd,
-			 show_remote_protocol_packet_cmd,
-			 &remote_set_cmdlist, &remote_show_cmdlist,
-			 1);
+			 "p", "fetch-register", 1, 0);
 
   add_packet_config_cmd (&remote_protocol_packets[PACKET_Z0],
-			 "Z0", "software-breakpoint",
-			 set_remote_protocol_packet_cmd,
-			 show_remote_protocol_packet_cmd,
-			 &remote_set_cmdlist, &remote_show_cmdlist,
-			 0);
+			 "Z0", "software-breakpoint", 0, 0);
 
   add_packet_config_cmd (&remote_protocol_packets[PACKET_Z1],
-			 "Z1", "hardware-breakpoint",
-			 set_remote_protocol_packet_cmd,
-			 show_remote_protocol_packet_cmd,
-			 &remote_set_cmdlist, &remote_show_cmdlist,
-			 0);
+			 "Z1", "hardware-breakpoint", 0, 0);
 
   add_packet_config_cmd (&remote_protocol_packets[PACKET_Z2],
-			 "Z2", "write-watchpoint",
-			 set_remote_protocol_packet_cmd,
-			 show_remote_protocol_packet_cmd,
-			 &remote_set_cmdlist, &remote_show_cmdlist,
-			 0);
+			 "Z2", "write-watchpoint", 0, 0);
 
   add_packet_config_cmd (&remote_protocol_packets[PACKET_Z3],
-			 "Z3", "read-watchpoint",
-			 set_remote_protocol_packet_cmd,
-			 show_remote_protocol_packet_cmd,
-			 &remote_set_cmdlist, &remote_show_cmdlist,
-			 0);
+			 "Z3", "read-watchpoint", 0, 0);
 
   add_packet_config_cmd (&remote_protocol_packets[PACKET_Z4],
-			 "Z4", "access-watchpoint",
-			 set_remote_protocol_packet_cmd,
-			 show_remote_protocol_packet_cmd,
-			 &remote_set_cmdlist, &remote_show_cmdlist,
-			 0);
+			 "Z4", "access-watchpoint",  0, 0);
 
   add_packet_config_cmd (&remote_protocol_packets[PACKET_qPart_auxv],
-			 "qPart_auxv", "read-aux-vector",
-			 set_remote_protocol_packet_cmd,
-			 show_remote_protocol_packet_cmd,
-			 &remote_set_cmdlist, &remote_show_cmdlist,
-			 0);
+			 "qPart:auxv", "read-aux-vector", 0, 0);
+
+  add_packet_config_cmd (&remote_protocol_packets[PACKET_qPart_features],
+			 "qPart:features", "target-features", 0, 1);
 
   add_packet_config_cmd (&remote_protocol_packets[PACKET_qGetTLSAddr],
 			 "qGetTLSAddr", "get-thread-local-storage-address",
-			 set_remote_protocol_packet_cmd,
-			 show_remote_protocol_packet_cmd,
-			 &remote_set_cmdlist, &remote_show_cmdlist,
-			 0);
+			 0, 0);
 
   /* Keep the old ``set remote Z-packet ...'' working.  Each individual
      Z sub-packet has its own set and show commands, but users may
diff --git a/gdb/sha1.c b/gdb/sha1.c
new file mode 100644
index 0000000..3b0d3bc
--- /dev/null
+++ b/gdb/sha1.c
@@ -0,0 +1,426 @@
+/* sha1.c - Functions to compute SHA1 message digest of files or
+   memory blocks according to the NIST specification FIPS-180-1.
+
+   Copyright (C) 2000, 2001, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+/* NOTE: The master copy of this file lives in GNU coreutils.  Please import
+   it from there.  */
+
+/* Written by Scott G. Miller
+   Credits:
+      Robert Klep <robert@ilse.nl>  -- Expansion function fix
+*/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "sha1.h"
+
+#include <stddef.h>
+#include <string.h>
+
+#if USE_UNLOCKED_IO
+# include "unlocked-io.h"
+#endif
+
+/* SWAP does an endian swap on architectures that are little-endian,
+   as SHA1 needs some data in a big-endian form.  */
+
+#ifdef WORDS_BIGENDIAN
+# define SWAP(n) (n)
+#else
+# define SWAP(n) \
+    (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24))
+#endif
+
+#define BLOCKSIZE 4096
+#if BLOCKSIZE % 64 != 0
+# error "invalid BLOCKSIZE"
+#endif
+
+/* This array contains the bytes used to pad the buffer to the next
+   64-byte boundary.  (RFC 1321, 3.1: Step 1)  */
+static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ...  */ };
+
+
+/*
+  Takes a pointer to a 160 bit block of data (five 32 bit ints) and
+  intializes it to the start constants of the SHA1 algorithm.  This
+  must be called before using hash in the call to sha1_hash.
+*/
+void
+sha1_init_ctx (struct sha1_ctx *ctx)
+{
+  ctx->A = 0x67452301;
+  ctx->B = 0xefcdab89;
+  ctx->C = 0x98badcfe;
+  ctx->D = 0x10325476;
+  ctx->E = 0xc3d2e1f0;
+
+  ctx->total[0] = ctx->total[1] = 0;
+  ctx->buflen = 0;
+}
+
+/* Put result from CTX in first 20 bytes following RESBUF.  The result
+   must be in little endian byte order.
+
+   IMPORTANT: On some systems it is required that RESBUF is correctly
+   aligned for a 32 bits value.  */
+void *
+sha1_read_ctx (const struct sha1_ctx *ctx, void *resbuf)
+{
+  ((md5_uint32 *) resbuf)[0] = SWAP (ctx->A);
+  ((md5_uint32 *) resbuf)[1] = SWAP (ctx->B);
+  ((md5_uint32 *) resbuf)[2] = SWAP (ctx->C);
+  ((md5_uint32 *) resbuf)[3] = SWAP (ctx->D);
+  ((md5_uint32 *) resbuf)[4] = SWAP (ctx->E);
+
+  return resbuf;
+}
+
+/* Process the remaining bytes in the internal buffer and the usual
+   prolog according to the standard and write the result to RESBUF.
+
+   IMPORTANT: On some systems it is required that RESBUF is correctly
+   aligned for a 32 bits value.  */
+void *
+sha1_finish_ctx (struct sha1_ctx *ctx, void *resbuf)
+{
+  /* Take yet unprocessed bytes into account.  */
+  md5_uint32 bytes = ctx->buflen;
+  size_t pad;
+
+  /* Now count remaining bytes.  */
+  ctx->total[0] += bytes;
+  if (ctx->total[0] < bytes)
+    ++ctx->total[1];
+
+  pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes;
+  memcpy (&ctx->buffer[bytes], fillbuf, pad);
+
+  /* Put the 64-bit file length in *bits* at the end of the buffer.  */
+  *(md5_uint32 *) &ctx->buffer[bytes + pad + 4] = SWAP (ctx->total[0] << 3);
+  *(md5_uint32 *) &ctx->buffer[bytes + pad] = SWAP ((ctx->total[1] << 3) |
+						    (ctx->total[0] >> 29));
+
+  /* Process last bytes.  */
+  sha1_process_block (ctx->buffer, bytes + pad + 8, ctx);
+
+  return sha1_read_ctx (ctx, resbuf);
+}
+
+/* Compute SHA1 message digest for bytes read from STREAM.  The
+   resulting message digest number will be written into the 16 bytes
+   beginning at RESBLOCK.  */
+int
+sha1_stream (FILE *stream, void *resblock)
+{
+  struct sha1_ctx ctx;
+  char buffer[BLOCKSIZE + 72];
+  size_t sum;
+
+  /* Initialize the computation context.  */
+  sha1_init_ctx (&ctx);
+
+  /* Iterate over full file contents.  */
+  while (1)
+    {
+      /* We read the file in blocks of BLOCKSIZE bytes.  One call of the
+	 computation function processes the whole buffer so that with the
+	 next round of the loop another block can be read.  */
+      size_t n;
+      sum = 0;
+
+      /* Read block.  Take care for partial reads.  */
+      while (1)
+	{
+	  n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream);
+
+	  sum += n;
+
+	  if (sum == BLOCKSIZE)
+	    break;
+
+	  if (n == 0)
+	    {
+	      /* Check for the error flag IFF N == 0, so that we don't
+		 exit the loop after a partial read due to e.g., EAGAIN
+		 or EWOULDBLOCK.  */
+	      if (ferror (stream))
+		return 1;
+	      goto process_partial_block;
+	    }
+
+	  /* We've read at least one byte, so ignore errors.  But always
+	     check for EOF, since feof may be true even though N > 0.
+	     Otherwise, we could end up calling fread after EOF.  */
+	  if (feof (stream))
+	    goto process_partial_block;
+	}
+
+      /* Process buffer with BLOCKSIZE bytes.  Note that
+			BLOCKSIZE % 64 == 0
+       */
+      sha1_process_block (buffer, BLOCKSIZE, &ctx);
+    }
+
+ process_partial_block:;
+
+  /* Process any remaining bytes.  */
+  if (sum > 0)
+    sha1_process_bytes (buffer, sum, &ctx);
+
+  /* Construct result in desired memory.  */
+  sha1_finish_ctx (&ctx, resblock);
+  return 0;
+}
+
+/* Compute MD5 message digest for LEN bytes beginning at BUFFER.  The
+   result is always in little endian byte order, so that a byte-wise
+   output yields to the wanted ASCII representation of the message
+   digest.  */
+void *
+sha1_buffer (const char *buffer, size_t len, void *resblock)
+{
+  struct sha1_ctx ctx;
+
+  /* Initialize the computation context.  */
+  sha1_init_ctx (&ctx);
+
+  /* Process whole buffer but last len % 64 bytes.  */
+  sha1_process_bytes (buffer, len, &ctx);
+
+  /* Put result in desired memory area.  */
+  return sha1_finish_ctx (&ctx, resblock);
+}
+
+void
+sha1_process_bytes (const void *buffer, size_t len, struct sha1_ctx *ctx)
+{
+  /* When we already have some bits in our internal buffer concatenate
+     both inputs first.  */
+  if (ctx->buflen != 0)
+    {
+      size_t left_over = ctx->buflen;
+      size_t add = 128 - left_over > len ? len : 128 - left_over;
+
+      memcpy (&ctx->buffer[left_over], buffer, add);
+      ctx->buflen += add;
+
+      if (ctx->buflen > 64)
+	{
+	  sha1_process_block (ctx->buffer, ctx->buflen & ~63, ctx);
+
+	  ctx->buflen &= 63;
+	  /* The regions in the following copy operation cannot overlap.  */
+	  memcpy (ctx->buffer, &ctx->buffer[(left_over + add) & ~63],
+		  ctx->buflen);
+	}
+
+      buffer = (const char *) buffer + add;
+      len -= add;
+    }
+
+  /* Process available complete blocks.  */
+  if (len >= 64)
+    {
+#if !_STRING_ARCH_unaligned
+# define alignof(type) offsetof (struct { char c; type x; }, x)
+# define UNALIGNED_P(p) (((size_t) p) % alignof (md5_uint32) != 0)
+      if (UNALIGNED_P (buffer))
+	while (len > 64)
+	  {
+	    sha1_process_block (memcpy (ctx->buffer, buffer, 64), 64, ctx);
+	    buffer = (const char *) buffer + 64;
+	    len -= 64;
+	  }
+      else
+#endif
+	{
+	  sha1_process_block (buffer, len & ~63, ctx);
+	  buffer = (const char *) buffer + (len & ~63);
+	  len &= 63;
+	}
+    }
+
+  /* Move remaining bytes in internal buffer.  */
+  if (len > 0)
+    {
+      size_t left_over = ctx->buflen;
+
+      memcpy (&ctx->buffer[left_over], buffer, len);
+      left_over += len;
+      if (left_over >= 64)
+	{
+	  sha1_process_block (ctx->buffer, 64, ctx);
+	  left_over -= 64;
+	  memcpy (ctx->buffer, &ctx->buffer[64], left_over);
+	}
+      ctx->buflen = left_over;
+    }
+}
+
+/* --- Code below is the primary difference between md5.c and sha1.c --- */
+
+/* SHA1 round constants */
+#define K1 0x5a827999L
+#define K2 0x6ed9eba1L
+#define K3 0x8f1bbcdcL
+#define K4 0xca62c1d6L
+
+/* Round functions.  Note that F2 is the same as F4.  */
+#define F1(B,C,D) ( D ^ ( B & ( C ^ D ) ) )
+#define F2(B,C,D) (B ^ C ^ D)
+#define F3(B,C,D) ( ( B & C ) | ( D & ( B | C ) ) )
+#define F4(B,C,D) (B ^ C ^ D)
+
+/* Process LEN bytes of BUFFER, accumulating context into CTX.
+   It is assumed that LEN % 64 == 0.
+   Most of this code comes from GnuPG's cipher/sha1.c.  */
+
+void
+sha1_process_block (const void *buffer, size_t len, struct sha1_ctx *ctx)
+{
+  const md5_uint32 *words = buffer;
+  size_t nwords = len / sizeof (md5_uint32);
+  const md5_uint32 *endp = words + nwords;
+  md5_uint32 x[16];
+  md5_uint32 a = ctx->A;
+  md5_uint32 b = ctx->B;
+  md5_uint32 c = ctx->C;
+  md5_uint32 d = ctx->D;
+  md5_uint32 e = ctx->E;
+
+  /* First increment the byte count.  RFC 1321 specifies the possible
+     length of the file up to 2^64 bits.  Here we only compute the
+     number of bytes.  Do a double word increment.  */
+  ctx->total[0] += len;
+  if (ctx->total[0] < len)
+    ++ctx->total[1];
+
+#define rol(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
+
+#define M(I) ( tm =   x[I&0x0f] ^ x[(I-14)&0x0f] \
+		    ^ x[(I-8)&0x0f] ^ x[(I-3)&0x0f] \
+	       , (x[I&0x0f] = rol(tm, 1)) )
+
+#define R(A,B,C,D,E,F,K,M)  do { E += rol( A, 5 )     \
+				      + F( B, C, D )  \
+				      + K	      \
+				      + M;	      \
+				 B = rol( B, 30 );    \
+			       } while(0)
+
+  while (words < endp)
+    {
+      md5_uint32 tm;
+      int t;
+      for (t = 0; t < 16; t++)
+	{
+	  x[t] = SWAP (*words);
+	  words++;
+	}
+
+      R( a, b, c, d, e, F1, K1, x[ 0] );
+      R( e, a, b, c, d, F1, K1, x[ 1] );
+      R( d, e, a, b, c, F1, K1, x[ 2] );
+      R( c, d, e, a, b, F1, K1, x[ 3] );
+      R( b, c, d, e, a, F1, K1, x[ 4] );
+      R( a, b, c, d, e, F1, K1, x[ 5] );
+      R( e, a, b, c, d, F1, K1, x[ 6] );
+      R( d, e, a, b, c, F1, K1, x[ 7] );
+      R( c, d, e, a, b, F1, K1, x[ 8] );
+      R( b, c, d, e, a, F1, K1, x[ 9] );
+      R( a, b, c, d, e, F1, K1, x[10] );
+      R( e, a, b, c, d, F1, K1, x[11] );
+      R( d, e, a, b, c, F1, K1, x[12] );
+      R( c, d, e, a, b, F1, K1, x[13] );
+      R( b, c, d, e, a, F1, K1, x[14] );
+      R( a, b, c, d, e, F1, K1, x[15] );
+      R( e, a, b, c, d, F1, K1, M(16) );
+      R( d, e, a, b, c, F1, K1, M(17) );
+      R( c, d, e, a, b, F1, K1, M(18) );
+      R( b, c, d, e, a, F1, K1, M(19) );
+      R( a, b, c, d, e, F2, K2, M(20) );
+      R( e, a, b, c, d, F2, K2, M(21) );
+      R( d, e, a, b, c, F2, K2, M(22) );
+      R( c, d, e, a, b, F2, K2, M(23) );
+      R( b, c, d, e, a, F2, K2, M(24) );
+      R( a, b, c, d, e, F2, K2, M(25) );
+      R( e, a, b, c, d, F2, K2, M(26) );
+      R( d, e, a, b, c, F2, K2, M(27) );
+      R( c, d, e, a, b, F2, K2, M(28) );
+      R( b, c, d, e, a, F2, K2, M(29) );
+      R( a, b, c, d, e, F2, K2, M(30) );
+      R( e, a, b, c, d, F2, K2, M(31) );
+      R( d, e, a, b, c, F2, K2, M(32) );
+      R( c, d, e, a, b, F2, K2, M(33) );
+      R( b, c, d, e, a, F2, K2, M(34) );
+      R( a, b, c, d, e, F2, K2, M(35) );
+      R( e, a, b, c, d, F2, K2, M(36) );
+      R( d, e, a, b, c, F2, K2, M(37) );
+      R( c, d, e, a, b, F2, K2, M(38) );
+      R( b, c, d, e, a, F2, K2, M(39) );
+      R( a, b, c, d, e, F3, K3, M(40) );
+      R( e, a, b, c, d, F3, K3, M(41) );
+      R( d, e, a, b, c, F3, K3, M(42) );
+      R( c, d, e, a, b, F3, K3, M(43) );
+      R( b, c, d, e, a, F3, K3, M(44) );
+      R( a, b, c, d, e, F3, K3, M(45) );
+      R( e, a, b, c, d, F3, K3, M(46) );
+      R( d, e, a, b, c, F3, K3, M(47) );
+      R( c, d, e, a, b, F3, K3, M(48) );
+      R( b, c, d, e, a, F3, K3, M(49) );
+      R( a, b, c, d, e, F3, K3, M(50) );
+      R( e, a, b, c, d, F3, K3, M(51) );
+      R( d, e, a, b, c, F3, K3, M(52) );
+      R( c, d, e, a, b, F3, K3, M(53) );
+      R( b, c, d, e, a, F3, K3, M(54) );
+      R( a, b, c, d, e, F3, K3, M(55) );
+      R( e, a, b, c, d, F3, K3, M(56) );
+      R( d, e, a, b, c, F3, K3, M(57) );
+      R( c, d, e, a, b, F3, K3, M(58) );
+      R( b, c, d, e, a, F3, K3, M(59) );
+      R( a, b, c, d, e, F4, K4, M(60) );
+      R( e, a, b, c, d, F4, K4, M(61) );
+      R( d, e, a, b, c, F4, K4, M(62) );
+      R( c, d, e, a, b, F4, K4, M(63) );
+      R( b, c, d, e, a, F4, K4, M(64) );
+      R( a, b, c, d, e, F4, K4, M(65) );
+      R( e, a, b, c, d, F4, K4, M(66) );
+      R( d, e, a, b, c, F4, K4, M(67) );
+      R( c, d, e, a, b, F4, K4, M(68) );
+      R( b, c, d, e, a, F4, K4, M(69) );
+      R( a, b, c, d, e, F4, K4, M(70) );
+      R( e, a, b, c, d, F4, K4, M(71) );
+      R( d, e, a, b, c, F4, K4, M(72) );
+      R( c, d, e, a, b, F4, K4, M(73) );
+      R( b, c, d, e, a, F4, K4, M(74) );
+      R( a, b, c, d, e, F4, K4, M(75) );
+      R( e, a, b, c, d, F4, K4, M(76) );
+      R( d, e, a, b, c, F4, K4, M(77) );
+      R( c, d, e, a, b, F4, K4, M(78) );
+      R( b, c, d, e, a, F4, K4, M(79) );
+
+      a = ctx->A += a;
+      b = ctx->B += b;
+      c = ctx->C += c;
+      d = ctx->D += d;
+      e = ctx->E += e;
+    }
+}
diff --git a/gdb/sha1.h b/gdb/sha1.h
new file mode 100644
index 0000000..9831a524
--- /dev/null
+++ b/gdb/sha1.h
@@ -0,0 +1,97 @@
+/* Declarations of functions and data types used for SHA1 sum
+   library functions.
+   Copyright (C) 2000, 2001, 2003, 2005 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+/* NOTE: The master copy of this file lives in GNU coreutils.  Please import
+   it from there.  Only minimal changes have been made, and marked with
+   IN_GDB.  */
+#define IN_GDB
+
+#ifndef SHA1_H
+# define SHA1_H 1
+
+# include <stdio.h>
+# ifdef IN_GDB
+#  include "gdb_stdint.h"
+#  define md5_uint32 uint32_t
+# else
+#  include "md5.h"
+# endif
+
+/* Structure to save state of computation between the single steps.  */
+struct sha1_ctx
+{
+  md5_uint32 A;
+  md5_uint32 B;
+  md5_uint32 C;
+  md5_uint32 D;
+  md5_uint32 E;
+
+  md5_uint32 total[2];
+  md5_uint32 buflen;
+  char buffer[128] __attribute__ ((__aligned__ (__alignof__ (md5_uint32))));
+};
+
+
+/* Initialize structure containing state of computation. */
+extern void sha1_init_ctx (struct sha1_ctx *ctx);
+
+/* Starting with the result of former calls of this function (or the
+   initialization function update the context for the next LEN bytes
+   starting at BUFFER.
+   It is necessary that LEN is a multiple of 64!!! */
+extern void sha1_process_block (const void *buffer, size_t len,
+				struct sha1_ctx *ctx);
+
+/* Starting with the result of former calls of this function (or the
+   initialization function update the context for the next LEN bytes
+   starting at BUFFER.
+   It is NOT required that LEN is a multiple of 64.  */
+extern void sha1_process_bytes (const void *buffer, size_t len,
+				struct sha1_ctx *ctx);
+
+/* Process the remaining bytes in the buffer and put result from CTX
+   in first 20 bytes following RESBUF.  The result is always in little
+   endian byte order, so that a byte-wise output yields to the wanted
+   ASCII representation of the message digest.
+
+   IMPORTANT: On some systems it is required that RESBUF be correctly
+   aligned for a 32 bits value.  */
+extern void *sha1_finish_ctx (struct sha1_ctx *ctx, void *resbuf);
+
+
+/* Put result from CTX in first 20 bytes following RESBUF.  The result is
+   always in little endian byte order, so that a byte-wise output yields
+   to the wanted ASCII representation of the message digest.
+
+   IMPORTANT: On some systems it is required that RESBUF is correctly
+   aligned for a 32 bits value.  */
+extern void *sha1_read_ctx (const struct sha1_ctx *ctx, void *resbuf);
+
+
+/* Compute SHA1 message digest for bytes read from STREAM.  The
+   resulting message digest number will be written into the 20 bytes
+   beginning at RESBLOCK.  */
+extern int sha1_stream (FILE *stream, void *resblock);
+
+/* Compute SHA1 message digest for LEN bytes beginning at BUFFER.  The
+   result is always in little endian byte order, so that a byte-wise
+   output yields to the wanted ASCII representation of the message
+   digest.  */
+extern void *sha1_buffer (const char *buffer, size_t len, void *resblock);
+
+#endif
diff --git a/gdb/sparc-tdep.c b/gdb/sparc-tdep.c
index dc6c534..aacdaa6 100644
--- a/gdb/sparc-tdep.c
+++ b/gdb/sparc-tdep.c
@@ -157,7 +157,7 @@
   gdb_byte buf[8];
   int len;
 
-  len = target_read_partial (ops, TARGET_OBJECT_WCOOKIE, NULL, buf, 0, 8);
+  len = target_read (ops, TARGET_OBJECT_WCOOKIE, NULL, buf, 0, 8);
   if (len == -1)
     return 0;
 
diff --git a/gdb/stack.c b/gdb/stack.c
index 435bb0c..9193046 100644
--- a/gdb/stack.c
+++ b/gdb/stack.c
@@ -1909,7 +1909,7 @@
 
   if (!found)
     printf_filtered (_("'%s' not within current stack frame.\n"), arg);
-  else if (frame != deprecated_selected_frame)
+  else if (frame != get_selected_frame (NULL))
     select_and_print_frame (frame);
 }
 
@@ -1918,7 +1918,7 @@
 enum language
 get_frame_language (void)
 {
-  struct frame_info *frame = deprecated_selected_frame;
+  struct frame_info *frame = deprecated_safe_get_selected_frame ();
 
   if (frame)
     {
diff --git a/gdb/symfile.c b/gdb/symfile.c
index 59cd3dc..a4c883b 100644
--- a/gdb/symfile.c
+++ b/gdb/symfile.c
@@ -1516,7 +1516,10 @@
    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;
+/* FIXME drow/2006-03-30: This used to be 512.  The remote target will
+   throttle it if it's too large; is there any use in having a small
+   value here?  */
+static int download_write_size = 16384;
 static void
 show_download_write_size (struct ui_file *file, int from_tty,
 			  struct cmd_list_element *c, const char *value)
diff --git a/gdb/symfile.h b/gdb/symfile.h
index 0cbd1fc..10361e7 100644
--- a/gdb/symfile.h
+++ b/gdb/symfile.h
@@ -25,6 +25,8 @@
 
 /* This file requires that you first include "bfd.h".  */
 
+#include "symtab.h"
+
 /* Opaque declarations.  */
 struct section_table;
 struct objfile;
diff --git a/gdb/target.c b/gdb/target.c
index 3da3e65..1d4e035 100644
--- a/gdb/target.c
+++ b/gdb/target.c
@@ -457,6 +457,7 @@
       INHERIT (to_find_memory_regions, t);
       INHERIT (to_make_corefile_notes, t);
       INHERIT (to_get_thread_local_address, t);
+      /* Do not inherit to_available_features.  */
       INHERIT (to_magic, t);
     }
 #undef INHERIT
@@ -634,6 +635,7 @@
   de_fault (to_async, 
 	    (void (*) (void (*) (enum inferior_event_type, void*), void*)) 
 	    tcomplain);
+  current_target.to_available_features = NULL;
 #undef de_fault
 
   /* Finally, position the target-stack beneath the squashed
@@ -1378,8 +1380,9 @@
 					  (gdb_byte *) buf + xfered,
 					  offset + xfered, len - xfered);
       /* Call an observer, notifying them of the xfer progress?  */
-      if (xfer <= 0)
-	/* Call memory_error?  */
+      if (xfer == 0)
+	return xfered;
+      if (xfer < 0)
 	return -1;
       xfered += xfer;
       QUIT;
@@ -1400,8 +1403,9 @@
 					   (gdb_byte *) buf + xfered,
 					   offset + xfered, len - xfered);
       /* Call an observer, notifying them of the xfer progress?  */
-      if (xfer <= 0)
-	/* Call memory_error?  */
+      if (xfer == 0)
+	return xfered;
+      if (xfer < 0)
 	return -1;
       xfered += xfer;
       QUIT;
@@ -1409,6 +1413,47 @@
   return len;
 }
 
+/* Perform a full target read of unknown size.  */
+
+LONGEST
+target_read_whole (struct target_ops *ops,
+		   enum target_object object,
+		   const char *annex, gdb_byte **buf_p)
+{
+  /* FIXME: Should we use the memory write size parameters for this
+     too?  Or something at another level entirely?  */
+  size_t buf_alloc = 32768, buf_pos = 0;
+  gdb_byte *buf = xmalloc (buf_alloc);
+  LONGEST n, total;
+
+  total = 0;
+  while (1)
+    {
+      n = target_read (ops, object, annex, &buf[buf_pos],
+		       buf_pos, buf_alloc - buf_pos);
+      if (n < 0)
+	{
+	  /* An error occurred.  */
+	  xfree (buf);
+	  return -1;
+	}
+
+      buf_pos += n;
+      if (buf_pos < buf_alloc)
+	{
+	  /* Read all there was.  */
+	  if (buf_pos == 0)
+	    xfree (buf);
+	  else
+	    *buf_p = buf;
+	  return buf_pos;
+	}
+
+      buf_alloc *= 2;
+      buf = xrealloc (buf, buf_alloc);
+    }
+}
+
 /* Memory transfer methods.  */
 
 void
@@ -1526,6 +1571,28 @@
 		  "could not find a target to follow fork");
 }
 
+/* Look for a target which can report architectural features, starting
+   from TARGET.  If we find one, return its features, using OBSTACK
+   for any temporary allocation.  */
+
+struct gdb_feature_set *
+target_available_features (struct target_ops *target, struct obstack *obstack)
+{
+  struct target_ops *t;
+
+  for (t = target; t != NULL; t = t->beneath)
+    if (t->to_available_features != NULL)
+      {
+	struct gdb_feature_set *features;
+
+	features = t->to_available_features (t, obstack);
+	if (features)
+	  return features;
+      }
+
+  return NULL;
+}
+
 /* 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.
diff --git a/gdb/target.h b/gdb/target.h
index b804b05..76d53d8 100644
--- a/gdb/target.h
+++ b/gdb/target.h
@@ -30,6 +30,7 @@
 struct ui_file;
 struct mem_attrib;
 struct target_ops;
+struct gdb_feature_set;
 
 /* This include file defines the interface between the main part
    of the debugger, and the part which is target-specific, or
@@ -230,7 +231,12 @@
   /* Transfer auxilliary vector.  */
   TARGET_OBJECT_AUXV,
   /* StackGhost cookie.  See "sparc-tdep.c".  */
-  TARGET_OBJECT_WCOOKIE
+  TARGET_OBJECT_WCOOKIE,
+  /* Available target-specific features, e.g. registers and coprocessors.
+     See "available.c".  With an empty ANNEX this fetches a list of
+     features; with a comma-separated list of features in ANNEX this
+     fetches the details of the listed features.  */
+  TARGET_OBJECT_AVAILABLE_FEATURES
 
   /* Possible future objects: TARGET_OBJECT_FILE, TARGET_OBJECT_PROC, ... */
 };
@@ -245,7 +251,10 @@
 				     const char *annex, const gdb_byte *buf,
 				     ULONGEST offset, LONGEST len);
 
-/* Wrappers to perform the full transfer.  */
+/* Wrappers to perform a full transfer.  These functions take the
+   same arguments as the partial versions, above, but a return
+   value of a positive number less than LEN implies that no more
+   data can be read or written.  */
 extern LONGEST target_read (struct target_ops *ops,
 			    enum target_object object,
 			    const char *annex, gdb_byte *buf,
@@ -256,6 +265,22 @@
 			     const char *annex, const gdb_byte *buf,
 			     ULONGEST offset, LONGEST len);
 
+/* Wrappers to perform a full read of unknown size.  OBJECT/ANNEX will
+   be read using OPS.  The return value will be -1 if the transfer
+   fails or is not supported; 0 if the object is empty; and the length
+   of the object otherwise.  If a positive value is returned, a
+   sufficiently large buffer will be allocated using xmalloc and
+   returned in *BUF_P containing the contents of the object.
+
+   This method should be used for objects sufficiently small to store
+   in a single xmalloced buffer, when no fixed bound on the object's
+   size is known in advance.  Don't try to read TARGET_OBJECT_MEMORY
+   through this function.  */
+
+extern LONGEST target_read_whole (struct target_ops *ops,
+				  enum target_object object,
+				  const char *annex, gdb_byte **buf_p);
+
 /* Wrappers to target read/write that perform memory transfers.  They
    throw an error if the memory transfer fails.
 
@@ -423,6 +448,13 @@
 				gdb_byte *readbuf, const gdb_byte *writebuf,
 				ULONGEST offset, LONGEST len);
 
+    /* Describe the architecture-specific features of this target.
+       Returns the features found.  All pointers refer either to
+       constants or temporary memory allocated on the provided
+       obstack.  */
+    struct gdb_feature_set *(*to_available_features) (struct target_ops *ops,
+						      struct obstack *obstack);
+
     int to_magic;
     /* Need sub-structure for target machine related rather than comm related?
      */
@@ -1074,6 +1106,9 @@
 #define target_stopped_data_address_p(CURRENT_TARGET) (1)
 #endif
 
+extern struct gdb_feature_set *target_available_features (struct target_ops *,
+							  struct obstack *);
+
 /* This will only be defined by a target that supports catching vfork events,
    such as HP-UX.
 
diff --git a/gdb/testsuite/gdb.base/default.exp b/gdb/testsuite/gdb.base/default.exp
index 1ecf1f7..784fe8c 100644
--- a/gdb/testsuite/gdb.base/default.exp
+++ b/gdb/testsuite/gdb.base/default.exp
@@ -167,7 +167,7 @@
 #test disable display
 gdb_test "disable display" "" "disable display"
 #test disassemble
-gdb_test "disassemble" "No frame selected." "disassemble"
+gdb_test "disassemble" "No (frame selected|registers)." "disassemble"
 #test display
 gdb_test "display" "" "display"
 #test do
@@ -229,9 +229,9 @@
 }
 
 #test frame "f" abbreviation
-gdb_test "f" "No stack." "frame \"f\" abbreviation"
+gdb_test "f" "No (stack|registers)." "frame \"f\" abbreviation"
 #test frame
-gdb_test "frame" "No stack." "frame"
+gdb_test "frame" "No (stack|registers)." "frame"
 #test fg
 gdb_test "fg" "The program is not being run." "fg"
 # FIXME: fg kills the udi connection
@@ -294,9 +294,9 @@
 #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"
+gdb_test "info all-registers" "(The program has no registers now|No registers)." "info all-registers"
 #test info args
-gdb_test "info args" "No frame selected." "info args"
+gdb_test "info args" "No (frame selected|registers)." "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
@@ -320,11 +320,11 @@
 #test info files
 gdb_test "info files" "" "info files"
 #test info float
-gdb_test "info float" "The program has no registers now." "info float"
+gdb_test "info float" "(The program has no registers now|No registers)." "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"
+gdb_test "info locals" "(No frame selected|No registers)." "info locals"
 #test info program
 gdb_test "info program" "The program being debugged is not being run." "info program"
 #test info registers
@@ -352,7 +352,7 @@
 #test info variables
 gdb_test "info variables" "All defined variables:" "info variables"
 #test info vector
-gdb_test "info vector" "The program has no registers now." "info vector"
+gdb_test "info vector" "(The program has no registers now|No registers)." "info vector"
 #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
diff --git a/gdb/tui/tui-disasm.c b/gdb/tui/tui-disasm.c
index 676f492..3c017eb 100644
--- a/gdb/tui/tui-disasm.c
+++ b/gdb/tui/tui-disasm.c
@@ -386,7 +386,7 @@
 
       content = (tui_win_content) TUI_DISASM_WIN->generic.content;
       if (cursal.symtab == (struct symtab *) NULL)
-	s = find_pc_symtab (get_frame_pc (deprecated_selected_frame));
+	s = find_pc_symtab (get_frame_pc (get_selected_frame (NULL)));
       else
 	s = cursal.symtab;
 
diff --git a/gdb/tui/tui-source.c b/gdb/tui/tui-source.c
index c7bcea6..b639ec3 100644
--- a/gdb/tui/tui-source.c
+++ b/gdb/tui/tui-source.c
@@ -330,7 +330,7 @@
       struct symtab_and_line cursal = get_current_source_symtab_and_line ();
 
       if (cursal.symtab == (struct symtab *) NULL)
-	s = find_pc_symtab (get_frame_pc (deprecated_selected_frame));
+	s = find_pc_symtab (get_frame_pc (get_selected_frame (NULL)));
       else
 	s = cursal.symtab;
 
diff --git a/gdb/tui/tui-winsource.c b/gdb/tui/tui-winsource.c
index d7ca706..5d6949a 100644
--- a/gdb/tui/tui-winsource.c
+++ b/gdb/tui/tui-winsource.c
@@ -314,7 +314,7 @@
       struct symtab_and_line cursal = get_current_source_symtab_and_line ();
 
       if (cursal.symtab == (struct symtab *) NULL)
-	s = find_pc_symtab (get_frame_pc (deprecated_selected_frame));
+	s = find_pc_symtab (get_frame_pc (get_selected_frame (NULL)));
       else
 	s = cursal.symtab;
 
diff --git a/gdb/valops.c b/gdb/valops.c
index e86b532..d346238 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -544,7 +544,7 @@
   /* Since modifying a register can trash the frame chain, and modifying memory
      can trash the frame cache, we save the old frame and then restore the new
      frame afterwards.  */
-  old_frame = get_frame_id (deprecated_selected_frame);
+  old_frame = get_frame_id (deprecated_safe_get_selected_frame ());
 
   switch (VALUE_LVAL (toval))
     {
@@ -2605,16 +2605,18 @@
   struct symbol *func, *sym;
   struct block *b;
   struct value * ret;
+  struct frame_info *frame;
 
-  if (deprecated_selected_frame == 0)
+  if (complain)
+    frame = get_selected_frame (_("no frame selected"));
+  else
     {
-      if (complain)
-	error (_("no frame selected"));
-      else
+      frame = deprecated_safe_get_selected_frame ();
+      if (frame == 0)
 	return 0;
     }
 
-  func = get_frame_function (deprecated_selected_frame);
+  func = get_frame_function (frame);
   if (!func)
     {
       if (complain)
@@ -2643,7 +2645,7 @@
 	return NULL;
     }
 
-  ret = read_var_value (sym, deprecated_selected_frame);
+  ret = read_var_value (sym, frame);
   if (ret == 0 && complain)
     error (_("`%s' argument unreadable"), name);
   return ret;
diff --git a/gdb/varobj.c b/gdb/varobj.c
index 76ced13..532d819 100644
--- a/gdb/varobj.c
+++ b/gdb/varobj.c
@@ -498,7 +498,7 @@
       if (fi != NULL)
 	{
 	  var->root->frame = get_frame_id (fi);
-	  old_fi = deprecated_selected_frame;
+	  old_fi = get_selected_frame (NULL);
 	  select_frame (fi);
 	}