diff options
Diffstat (limited to 'gdbsupport')
125 files changed, 27929 insertions, 0 deletions
diff --git a/gdbsupport/ChangeLog b/gdbsupport/ChangeLog new file mode 100644 index 0000000..bc32a00 --- /dev/null +++ b/gdbsupport/ChangeLog @@ -0,0 +1,7 @@ +2020-01-14 Tom Tromey <tom@tromey.com> + + * common-defs.h: Add GDBSERVER case. Update includes. + * acinclude.m4, aclocal.m4, config.in, configure, configure.ac, + Makefile.am, Makefile.in, README: New files. + * Moved from ../gdb/gdbsupport/ + diff --git a/gdbsupport/Makefile.am b/gdbsupport/Makefile.am new file mode 100644 index 0000000..48e6079 --- /dev/null +++ b/gdbsupport/Makefile.am @@ -0,0 +1,70 @@ +## Process this file with automake to generate Makefile.in +# +# Copyright (C) 2020 Free Software Foundation, Inc. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; see the file COPYING3. If not see +# <http://www.gnu.org/licenses/>. +# + +AUTOMAKE_OPTIONS = no-dist foreign +ACLOCAL_AMFLAGS = -I . -I ../config + +AM_CPPFLAGS = -I$(srcdir)/../include -I$(srcdir)/../gdb \ + -I../gnulib/import -I$(srcdir)/../gnulib/import \ + -I.. -I$(srcdir)/.. $(INCINTL) -I../bfd -I$(srcdir)/../bfd + +override CC := $(CXX) +override CFLAGS := $(CXXFLAGS) + +noinst_LIBRARIES = libgdbsupport.a + +if SELFTEST +selftest = selftest.c +endif + +libgdbsupport_a_SOURCES = \ + agent.c \ + btrace-common.c \ + buffer.c \ + cleanups.c \ + common-debug.c \ + common-exceptions.c \ + common-inferior.c \ + common-regcache.c \ + common-utils.c \ + environ.c \ + errors.c \ + fileio.c \ + filestuff.c \ + format.c \ + gdb-dlfcn.c \ + gdb_tilde_expand.c \ + gdb_wait.c \ + gdb_vecs.c \ + job-control.c \ + netstuff.c \ + new-op.c \ + pathstuff.c \ + print-utils.c \ + ptid.c \ + rsp-low.c \ + run-time-clock.c \ + safe-strerror.c \ + scoped_mmap.c \ + signals.c \ + signals-state-save-restore.c \ + tdesc.c \ + thread-pool.c \ + xml-utils.c \ + $(selftest) diff --git a/gdbsupport/Makefile.in b/gdbsupport/Makefile.in new file mode 100644 index 0000000..1986be8 --- /dev/null +++ b/gdbsupport/Makefile.in @@ -0,0 +1,688 @@ +# Makefile.in generated by automake 1.15.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2017 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# +# Copyright (C) 2020 Free Software Foundation, Inc. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; see the file COPYING3. If not see +# <http://www.gnu.org/licenses/>. +# + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +subdir = . +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/../config/codeset.m4 \ + $(top_srcdir)/../config/depstand.m4 \ + $(top_srcdir)/../config/gettext-sister.m4 \ + $(top_srcdir)/../config/largefile.m4 \ + $(top_srcdir)/../config/lead-dot.m4 \ + $(top_srcdir)/../config/override.m4 \ + $(top_srcdir)/../config/plugins.m4 $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/common.m4 $(top_srcdir)/../config/ax_pthread.m4 \ + $(top_srcdir)/../gdb/ax_cxx_compile_stdcxx.m4 \ + $(top_srcdir)/../gdb/libiberty.m4 \ + $(top_srcdir)/../gdb/selftest.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ + $(am__configure_deps) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno config.status.lineno +mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs +CONFIG_HEADER = support-config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LIBRARIES = $(noinst_LIBRARIES) +AR = ar +ARFLAGS = cru +AM_V_AR = $(am__v_AR_@AM_V@) +am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) +am__v_AR_0 = @echo " AR " $@; +am__v_AR_1 = +libgdbsupport_a_AR = $(AR) $(ARFLAGS) +libgdbsupport_a_LIBADD = +@SELFTEST_TRUE@am__objects_1 = selftest.$(OBJEXT) +am_libgdbsupport_a_OBJECTS = agent.$(OBJEXT) btrace-common.$(OBJEXT) \ + buffer.$(OBJEXT) cleanups.$(OBJEXT) common-debug.$(OBJEXT) \ + common-exceptions.$(OBJEXT) common-inferior.$(OBJEXT) \ + common-regcache.$(OBJEXT) common-utils.$(OBJEXT) \ + environ.$(OBJEXT) errors.$(OBJEXT) fileio.$(OBJEXT) \ + filestuff.$(OBJEXT) format.$(OBJEXT) gdb-dlfcn.$(OBJEXT) \ + gdb_tilde_expand.$(OBJEXT) gdb_wait.$(OBJEXT) \ + gdb_vecs.$(OBJEXT) job-control.$(OBJEXT) netstuff.$(OBJEXT) \ + new-op.$(OBJEXT) pathstuff.$(OBJEXT) print-utils.$(OBJEXT) \ + ptid.$(OBJEXT) rsp-low.$(OBJEXT) run-time-clock.$(OBJEXT) \ + safe-strerror.$(OBJEXT) scoped_mmap.$(OBJEXT) \ + signals.$(OBJEXT) signals-state-save-restore.$(OBJEXT) \ + tdesc.$(OBJEXT) thread-pool.$(OBJEXT) xml-utils.$(OBJEXT) \ + $(am__objects_1) +libgdbsupport_a_OBJECTS = $(am_libgdbsupport_a_OBJECTS) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ +depcomp = $(SHELL) $(top_srcdir)/../depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libgdbsupport_a_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ + $(LISP)config.in +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +CSCOPE = cscope +AM_RECURSIVE_TARGETS = cscope +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CATALOGS = @CATALOGS@ +CATOBJEXT = @CATOBJEXT@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CXX_DIALECT = @CXX_DIALECT@ +CYGPATH_W = @CYGPATH_W@ +DATADIRNAME = @DATADIRNAME@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GENCAT = @GENCAT@ +GMSGFMT = @GMSGFMT@ +GREP = @GREP@ +HAVE_CXX11 = @HAVE_CXX11@ +INCINTL = @INCINTL@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INSTOBJEXT = @INSTOBJEXT@ +LDFLAGS = @LDFLAGS@ +LIBINTL = @LIBINTL@ +LIBINTL_DEP = @LIBINTL_DEP@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +POSUB = @POSUB@ +PTHREAD_CC = @PTHREAD_CC@ +PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ +PTHREAD_LIBS = @PTHREAD_LIBS@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +XGETTEXT = @XGETTEXT@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +ax_pthread_config = @ax_pthread_config@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AUTOMAKE_OPTIONS = no-dist foreign +ACLOCAL_AMFLAGS = -I . -I ../config +AM_CPPFLAGS = -I$(srcdir)/../include -I$(srcdir)/../gdb \ + -I../gnulib/import -I$(srcdir)/../gnulib/import \ + -I.. -I$(srcdir)/.. $(INCINTL) -I../bfd -I$(srcdir)/../bfd + +noinst_LIBRARIES = libgdbsupport.a +@SELFTEST_TRUE@selftest = selftest.c +libgdbsupport_a_SOURCES = \ + agent.c \ + btrace-common.c \ + buffer.c \ + cleanups.c \ + common-debug.c \ + common-exceptions.c \ + common-inferior.c \ + common-regcache.c \ + common-utils.c \ + environ.c \ + errors.c \ + fileio.c \ + filestuff.c \ + format.c \ + gdb-dlfcn.c \ + gdb_tilde_expand.c \ + gdb_wait.c \ + gdb_vecs.c \ + job-control.c \ + netstuff.c \ + new-op.c \ + pathstuff.c \ + print-utils.c \ + ptid.c \ + rsp-low.c \ + run-time-clock.c \ + safe-strerror.c \ + scoped_mmap.c \ + signals.c \ + signals-state-save-restore.c \ + tdesc.c \ + thread-pool.c \ + xml-utils.c \ + $(selftest) + +all: support-config.h + $(MAKE) $(AM_MAKEFLAGS) all-am + +.SUFFIXES: +.SUFFIXES: .c .o .obj +am--refresh: Makefile + @: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ + $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + $(am__cd) $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) +$(am__aclocal_m4_deps): + +support-config.h: stamp-h1 + @test -f $@ || rm -f stamp-h1 + @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 + +stamp-h1: $(srcdir)/config.in $(top_builddir)/config.status + @rm -f stamp-h1 + cd $(top_builddir) && $(SHELL) ./config.status support-config.h +$(srcdir)/config.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) + rm -f stamp-h1 + touch $@ + +distclean-hdr: + -rm -f support-config.h stamp-h1 + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) + +libgdbsupport.a: $(libgdbsupport_a_OBJECTS) $(libgdbsupport_a_DEPENDENCIES) $(EXTRA_libgdbsupport_a_DEPENDENCIES) + $(AM_V_at)-rm -f libgdbsupport.a + $(AM_V_AR)$(libgdbsupport_a_AR) libgdbsupport.a $(libgdbsupport_a_OBJECTS) $(libgdbsupport_a_LIBADD) + $(AM_V_at)$(RANLIB) libgdbsupport.a + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/agent.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btrace-common.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/buffer.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cleanups.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/common-debug.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/common-exceptions.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/common-inferior.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/common-regcache.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/common-utils.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/environ.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/errors.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fileio.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/filestuff.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/format.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gdb-dlfcn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gdb_tilde_expand.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gdb_vecs.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gdb_wait.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/job-control.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netstuff.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/new-op.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pathstuff.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/print-utils.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ptid.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rsp-low.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run-time-clock.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/safe-strerror.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scoped_mmap.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/selftest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/signals-state-save-restore.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/signals.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tdesc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/thread-pool.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xml-utils.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscope: cscope.files + test ! -s cscope.files \ + || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) +clean-cscope: + -rm -f cscope.files +cscope.files: clean-cscope cscopelist +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + -rm -f cscope.out cscope.in.out cscope.po.out cscope.files +check-am: all-am +check: check-am +all-am: Makefile $(LIBRARIES) support-config.h +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am + +distclean: distclean-am + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-hdr distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: all install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--refresh check check-am clean \ + clean-cscope clean-generic clean-noinstLIBRARIES cscope \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-hdr distclean-tags dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am + +.PRECIOUS: Makefile + + +override CC := $(CXX) +override CFLAGS := $(CXXFLAGS) + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/gdbsupport/README b/gdbsupport/README new file mode 100644 index 0000000..257dcea --- /dev/null +++ b/gdbsupport/README @@ -0,0 +1,4 @@ +This is a helper library that is used by gdb and gdbserver. + +To send patches, follow the gdb patch submission instructions in +../gdb/CONTRIBUTE. For maintainers, see ../gdb/MAINTAINERS. diff --git a/gdbsupport/acinclude.m4 b/gdbsupport/acinclude.m4 new file mode 100644 index 0000000..6e20e9c --- /dev/null +++ b/gdbsupport/acinclude.m4 @@ -0,0 +1,5 @@ +m4_include([common.m4]) +m4_include([../config/ax_pthread.m4]) +m4_include([../gdb/ax_cxx_compile_stdcxx.m4]) +m4_include([../gdb/libiberty.m4]) +m4_include([../gdb/selftest.m4]) diff --git a/gdbsupport/aclocal.m4 b/gdbsupport/aclocal.m4 new file mode 100644 index 0000000..d0a839a5 --- /dev/null +++ b/gdbsupport/aclocal.m4 @@ -0,0 +1,1206 @@ +# generated automatically by aclocal 1.15.1 -*- Autoconf -*- + +# Copyright (C) 1996-2017 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 distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, +[m4_warning([this file was generated for autoconf 2.69. +You have another version of autoconf. It may work, but is not guaranteed to. +If you have problems, you may need to regenerate the build system entirely. +To do so, use the procedure documented by the package, typically 'autoreconf'.])]) + +# Copyright (C) 2002-2017 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. + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +# (This private macro should not be called outside this file.) +AC_DEFUN([AM_AUTOMAKE_VERSION], +[am__api_version='1.15' +dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to +dnl require some minimum version. Point them to the right macro. +m4_if([$1], [1.15.1], [], + [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl +]) + +# _AM_AUTOCONF_VERSION(VERSION) +# ----------------------------- +# aclocal traces this macro to find the Autoconf version. +# This is a private macro too. Using m4_define simplifies +# the logic in aclocal, which can simply ignore this definition. +m4_define([_AM_AUTOCONF_VERSION], []) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. +# This function is AC_REQUIREd by AM_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], +[AM_AUTOMAKE_VERSION([1.15.1])dnl +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) + +# AM_AUX_DIR_EXPAND -*- Autoconf -*- + +# Copyright (C) 2001-2017 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. + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to +# '$srcdir', '$srcdir/..', or '$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is '.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +AC_DEFUN([AM_AUX_DIR_EXPAND], +[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl +# Expand $ac_aux_dir to an absolute path. +am_aux_dir=`cd "$ac_aux_dir" && pwd` +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997-2017 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. + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ([2.52])dnl + m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE])dnl +AC_SUBST([$1_FALSE])dnl +_AM_SUBST_NOTMAKE([$1_TRUE])dnl +_AM_SUBST_NOTMAKE([$1_FALSE])dnl +m4_define([_AM_COND_VALUE_$1], [$2])dnl +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + +# Copyright (C) 1999-2017 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. + + +# There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], + [$1], [CXX], [depcc="$CXX" am_compiler_list=], + [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], + [$1], [UPC], [depcc="$UPC" am_compiler_list=], + [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + am__universal=false + m4_case([$1], [CC], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac], + [CXX], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac]) + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES. +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE([dependency-tracking], [dnl +AS_HELP_STRING( + [--enable-dependency-tracking], + [do not reject slow dependency extractors]) +AS_HELP_STRING( + [--disable-dependency-tracking], + [speeds up one-time build])]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH])dnl +_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl +AC_SUBST([am__nodep])dnl +_AM_SUBST_NOTMAKE([am__nodep])dnl +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright (C) 1999-2017 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. + + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[{ + # Older Autoconf quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named 'Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running 'make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "$am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking +# is enabled. FIXME. This creates each '.P' file that we will +# need in order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +]) + +# Do all the work for Automake. -*- Autoconf -*- + +# Copyright (C) 1996-2017 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 macro actually does too much. Some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. +m4_define([AC_PROG_CC], +m4_defn([AC_PROG_CC]) +[_AM_PROG_CC_C_O +]) + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.65])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[AC_DIAGNOSE([obsolete], + [$0: two- and three-arguments forms are deprecated.]) +m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl +dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. +m4_if( + m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), + [ok:ok],, + [m4_fatal([AC_INIT should be called with package and version arguments])])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) + AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) +AM_MISSING_PROG([AUTOCONF], [autoconf]) +AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) +AM_MISSING_PROG([AUTOHEADER], [autoheader]) +AM_MISSING_PROG([MAKEINFO], [makeinfo]) +AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html> +# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html> +AC_SUBST([mkdir_p], ['$(MKDIR_P)']) +# We need awk for the "check" target (and possibly the TAP driver). The +# system "awk" is bad on some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES([CC])], + [m4_define([AC_PROG_CC], + m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES([CXX])], + [m4_define([AC_PROG_CXX], + m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJC], + [_AM_DEPENDENCIES([OBJC])], + [m4_define([AC_PROG_OBJC], + m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], + [_AM_DEPENDENCIES([OBJCXX])], + [m4_define([AC_PROG_OBJCXX], + m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl +]) +AC_REQUIRE([AM_SILENT_RULES])dnl +dnl The testsuite driver may need to know about EXEEXT, so add the +dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This +dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. +AC_CONFIG_COMMANDS_PRE(dnl +[m4_provide_if([_AM_COMPILER_EXEEXT], + [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl + +# POSIX will say in a future version that running "rm -f" with no argument +# is OK; and we want to be able to make that assumption in our Makefile +# recipes. So use an aggressive probe to check that the usage we want is +# actually supported "in the wild" to an acceptable degree. +# See automake bug#10828. +# To make any issue more visible, cause the running configure to be aborted +# by default if the 'rm' program in use doesn't match our expectations; the +# user can still override this though. +if rm -f && rm -fr && rm -rf; then : OK; else + cat >&2 <<'END' +Oops! + +Your 'rm' program seems unable to run without file operands specified +on the command line, even when the '-f' option is present. This is contrary +to the behaviour of most rm programs out there, and not conforming with +the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542> + +Please tell bug-automake@gnu.org about your system, including the value +of your $PATH and any error possibly output before this message. This +can help us improve future automake versions. + +END + if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then + echo 'Configuration will proceed anyway, since you have set the' >&2 + echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 + echo >&2 + else + cat >&2 <<'END' +Aborting the configuration process, to ensure you take notice of the issue. + +You can download and install GNU coreutils to get an 'rm' implementation +that behaves properly: <http://www.gnu.org/software/coreutils/>. + +If you want to complete the configuration process using your problematic +'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +to "yes", and re-run configure. + +END + AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) + fi +fi +dnl The trailing newline in this macro's definition is deliberate, for +dnl backward compatibility and to allow trailing 'dnl'-style comments +dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841. +]) + +dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not +dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further +dnl mangled by Autoconf and run in a shell conditional statement. +m4_define([_AC_COMPILER_EXEEXT], +m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_arg=$1 +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) + +# Copyright (C) 2001-2017 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. + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +if test x"${install_sh+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi +AC_SUBST([install_sh])]) + +# Add --enable-maintainer-mode option to configure. -*- Autoconf -*- +# From Jim Meyering + +# Copyright (C) 1996-2017 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. + +# AM_MAINTAINER_MODE([DEFAULT-MODE]) +# ---------------------------------- +# Control maintainer-specific portions of Makefiles. +# Default is to disable them, unless 'enable' is passed literally. +# For symmetry, 'disable' may be passed as well. Anyway, the user +# can override the default with the --enable/--disable switch. +AC_DEFUN([AM_MAINTAINER_MODE], +[m4_case(m4_default([$1], [disable]), + [enable], [m4_define([am_maintainer_other], [disable])], + [disable], [m4_define([am_maintainer_other], [enable])], + [m4_define([am_maintainer_other], [enable]) + m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])]) +AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) + dnl maintainer-mode's default is 'disable' unless 'enable' is passed + AC_ARG_ENABLE([maintainer-mode], + [AS_HELP_STRING([--]am_maintainer_other[-maintainer-mode], + am_maintainer_other[ make rules and dependencies not useful + (and sometimes confusing) to the casual installer])], + [USE_MAINTAINER_MODE=$enableval], + [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes])) + AC_MSG_RESULT([$USE_MAINTAINER_MODE]) + AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes]) + MAINT=$MAINTAINER_MODE_TRUE + AC_SUBST([MAINT])dnl +] +) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001-2017 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. + +# AM_MAKE_INCLUDE() +# ----------------- +# Check to see how make treats includes. +AC_DEFUN([AM_MAKE_INCLUDE], +[am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +AC_MSG_CHECKING([for style of include used by $am_make]) +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from 'make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi +AC_SUBST([am__include]) +AC_SUBST([am__quote]) +AC_MSG_RESULT([$_am_result]) +rm -f confinc confmf +]) + +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +# Copyright (C) 1997-2017 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. + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it is modern enough. +# If it is, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([missing])dnl +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " +else + am_missing_run= + AC_MSG_WARN(['missing' script is too old or missing]) +fi +]) + +# -*- Autoconf -*- +# Obsolete and "removed" macros, that must however still report explicit +# error messages when used, to smooth transition. +# +# Copyright (C) 1996-2017 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. + +AC_DEFUN([AM_CONFIG_HEADER], +[AC_DIAGNOSE([obsolete], +['$0': this macro is obsolete. +You should use the 'AC][_CONFIG_HEADERS' macro instead.])dnl +AC_CONFIG_HEADERS($@)]) + +AC_DEFUN([AM_PROG_CC_STDC], +[AC_PROG_CC +am_cv_prog_cc_stdc=$ac_cv_prog_cc_stdc +AC_DIAGNOSE([obsolete], +['$0': this macro is obsolete. +You should simply use the 'AC][_PROG_CC' macro instead. +Also, your code should no longer depend upon 'am_cv_prog_cc_stdc', +but upon 'ac_cv_prog_cc_stdc'.])]) + +AC_DEFUN([AM_C_PROTOTYPES], + [AC_FATAL([automatic de-ANSI-fication support has been removed])]) +AU_DEFUN([fp_C_PROTOTYPES], [AM_C_PROTOTYPES]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001-2017 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. + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# -------------------- +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), [1])]) + +# _AM_SET_OPTIONS(OPTIONS) +# ------------------------ +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# Copyright (C) 1999-2017 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. + +# _AM_PROG_CC_C_O +# --------------- +# Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC +# to automatically call this. +AC_DEFUN([_AM_PROG_CC_C_O], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([compile])dnl +AC_LANG_PUSH([C])dnl +AC_CACHE_CHECK( + [whether $CC understands -c and -o together], + [am_cv_prog_cc_c_o], + [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i]) +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +AC_LANG_POP([C])]) + +# For backward compatibility. +AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) + +# Copyright (C) 2001-2017 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. + +# AM_RUN_LOG(COMMAND) +# ------------------- +# Run COMMAND, save the exit status in ac_status, and log it. +# (This has been adapted from Autoconf's _AC_RUN_LOG macro.) +AC_DEFUN([AM_RUN_LOG], +[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD + ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + (exit $ac_status); }]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996-2017 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. + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[[\\\"\#\$\&\'\`$am_lf]]*) + AC_MSG_ERROR([unsafe absolute working directory name]);; +esac +case $srcdir in + *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) + AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; +esac + +# Do 'set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken + alias in your environment]) + fi + if test "$[2]" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT([yes]) +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi +AC_CONFIG_COMMANDS_PRE( + [AC_MSG_CHECKING([that generated files are newer than configure]) + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + AC_MSG_RESULT([done])]) +rm -f conftest.file +]) + +# Copyright (C) 2009-2017 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. + +# AM_SILENT_RULES([DEFAULT]) +# -------------------------- +# Enable less verbose build rules; with the default set to DEFAULT +# ("yes" being less verbose, "no" or empty being verbose). +AC_DEFUN([AM_SILENT_RULES], +[AC_ARG_ENABLE([silent-rules], [dnl +AS_HELP_STRING( + [--enable-silent-rules], + [less verbose build output (undo: "make V=1")]) +AS_HELP_STRING( + [--disable-silent-rules], + [verbose build output (undo: "make V=0")])dnl +]) +case $enable_silent_rules in @%:@ ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; +esac +dnl +dnl A few 'make' implementations (e.g., NonStop OS and NextStep) +dnl do not support nested variable expansions. +dnl See automake bug#9928 and bug#10237. +am_make=${MAKE-make} +AC_CACHE_CHECK([whether $am_make supports nested variables], + [am_cv_make_support_nested_variables], + [if AS_ECHO([['TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi]) +if test $am_cv_make_support_nested_variables = yes; then + dnl Using '$V' instead of '$(V)' breaks IRIX make. + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AC_SUBST([AM_V])dnl +AM_SUBST_NOTMAKE([AM_V])dnl +AC_SUBST([AM_DEFAULT_V])dnl +AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl +AC_SUBST([AM_DEFAULT_VERBOSITY])dnl +AM_BACKSLASH='\' +AC_SUBST([AM_BACKSLASH])dnl +_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl +]) + +# Copyright (C) 2001-2017 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. + +# AM_PROG_INSTALL_STRIP +# --------------------- +# One issue with vendor 'install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in "make install-strip", and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the 'STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Copyright (C) 2006-2017 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. + +# _AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. +# This macro is traced by Automake. +AC_DEFUN([_AM_SUBST_NOTMAKE]) + +# AM_SUBST_NOTMAKE(VARIABLE) +# -------------------------- +# Public sister of _AM_SUBST_NOTMAKE. +AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004-2017 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. + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of 'v7', 'ustar', or 'pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +# +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AC_SUBST([AMTAR], ['$${TAR-tar}']) + +# We'll loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' + +m4_if([$1], [v7], + [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], + + [m4_case([$1], + [ustar], + [# The POSIX 1988 'ustar' format is defined with fixed-size fields. + # There is notably a 21 bits limit for the UID and the GID. In fact, + # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 + # and bug#13588). + am_max_uid=2097151 # 2^21 - 1 + am_max_gid=$am_max_uid + # The $UID and $GID variables are not portable, so we need to resort + # to the POSIX-mandated id(1) utility. Errors in the 'id' calls + # below are definitely unexpected, so allow the users to see them + # (that is, avoid stderr redirection). + am_uid=`id -u || echo unknown` + am_gid=`id -g || echo unknown` + AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) + if test $am_uid -le $am_max_uid; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + _am_tools=none + fi + AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) + if test $am_gid -le $am_max_gid; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + _am_tools=none + fi], + + [pax], + [], + + [m4_fatal([Unknown tar format])]) + + AC_MSG_CHECKING([how to create a $1 tar archive]) + + # Go ahead even if we have the value already cached. We do so because we + # need to set the values for the 'am__tar' and 'am__untar' variables. + _am_tools=${am_cv_prog_tar_$1-$_am_tools} + + for _am_tool in $_am_tools; do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works. + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar <conftest.tar]) + AM_RUN_LOG([cat conftest.dir/file]) + grep GrepMe conftest.dir/file >/dev/null 2>&1 && break + fi + done + rm -rf conftest.dir + + AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) + AC_MSG_RESULT([$am_cv_prog_tar_$1])]) + +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + +m4_include([../config/codeset.m4]) +m4_include([../config/depstand.m4]) +m4_include([../config/gettext-sister.m4]) +m4_include([../config/largefile.m4]) +m4_include([../config/lead-dot.m4]) +m4_include([../config/override.m4]) +m4_include([../config/plugins.m4]) +m4_include([acinclude.m4]) diff --git a/gdbsupport/agent.c b/gdbsupport/agent.c new file mode 100644 index 0000000..b4127ff --- /dev/null +++ b/gdbsupport/agent.c @@ -0,0 +1,280 @@ +/* Shared utility routines for GDB to interact with agent. + + Copyright (C) 2009-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "common-defs.h" +#include "target/target.h" +#include "gdbsupport/symbol.h" +#include <unistd.h> +#include "filestuff.h" + +#define IPA_SYM_STRUCT_NAME ipa_sym_addresses_common +#include "agent.h" + +bool debug_agent = false; + +/* A stdarg wrapper for debug_vprintf. */ + +static void ATTRIBUTE_PRINTF (1, 2) +debug_agent_printf (const char *fmt, ...) +{ + va_list ap; + + if (!debug_agent) + return; + va_start (ap, fmt); + debug_vprintf (fmt, ap); + va_end (ap); +} + +#define DEBUG_AGENT debug_agent_printf + +/* Global flag to determine using agent or not. */ +bool use_agent = false; + +/* Addresses of in-process agent's symbols both GDB and GDBserver cares + about. */ + +struct ipa_sym_addresses_common +{ + CORE_ADDR addr_helper_thread_id; + CORE_ADDR addr_cmd_buf; + CORE_ADDR addr_capability; +}; + +/* Cache of the helper thread id. FIXME: this global should be made + per-process. */ +static uint32_t helper_thread_id = 0; + +static struct +{ + const char *name; + int offset; +} symbol_list[] = { + IPA_SYM(helper_thread_id), + IPA_SYM(cmd_buf), + IPA_SYM(capability), +}; + +static struct ipa_sym_addresses_common ipa_sym_addrs; + +static bool all_agent_symbols_looked_up = false; + +bool +agent_loaded_p (void) +{ + return all_agent_symbols_looked_up; +} + +/* Look up all symbols needed by agent. Return 0 if all the symbols are + found, return non-zero otherwise. */ + +int +agent_look_up_symbols (void *arg) +{ + all_agent_symbols_looked_up = false; + + for (int i = 0; i < sizeof (symbol_list) / sizeof (symbol_list[0]); i++) + { + CORE_ADDR *addrp = + (CORE_ADDR *) ((char *) &ipa_sym_addrs + symbol_list[i].offset); + struct objfile *objfile = (struct objfile *) arg; + + if (find_minimal_symbol_address (symbol_list[i].name, addrp, + objfile) != 0) + { + DEBUG_AGENT ("symbol `%s' not found\n", symbol_list[i].name); + return -1; + } + } + + all_agent_symbols_looked_up = true; + return 0; +} + +static unsigned int +agent_get_helper_thread_id (void) +{ + if (helper_thread_id == 0) + { + if (target_read_uint32 (ipa_sym_addrs.addr_helper_thread_id, + &helper_thread_id)) + warning (_("Error reading helper thread's id in lib")); + } + + return helper_thread_id; +} + +#ifdef HAVE_SYS_UN_H +#include <sys/socket.h> +#include <sys/un.h> +#define SOCK_DIR P_tmpdir + +#ifndef UNIX_PATH_MAX +#define UNIX_PATH_MAX sizeof(((struct sockaddr_un *) NULL)->sun_path) +#endif + +#endif + +/* Connects to synchronization socket. PID is the pid of inferior, which is + used to set up the connection socket. */ + +static int +gdb_connect_sync_socket (int pid) +{ +#ifdef HAVE_SYS_UN_H + struct sockaddr_un addr; + int res, fd; + char path[UNIX_PATH_MAX]; + + res = xsnprintf (path, UNIX_PATH_MAX, "%s/gdb_ust%d", P_tmpdir, pid); + if (res >= UNIX_PATH_MAX) + return -1; + + res = fd = gdb_socket_cloexec (PF_UNIX, SOCK_STREAM, 0); + if (res == -1) + { + warning (_("error opening sync socket: %s"), safe_strerror (errno)); + return -1; + } + + addr.sun_family = AF_UNIX; + + res = xsnprintf (addr.sun_path, UNIX_PATH_MAX, "%s", path); + if (res >= UNIX_PATH_MAX) + { + warning (_("string overflow allocating socket name")); + close (fd); + return -1; + } + + res = connect (fd, (struct sockaddr *) &addr, sizeof (addr)); + if (res == -1) + { + warning (_("error connecting sync socket (%s): %s. " + "Make sure the directory exists and that it is writable."), + path, safe_strerror (errno)); + close (fd); + return -1; + } + + return fd; +#else + return -1; +#endif +} + +/* Execute an agent command in the inferior. PID is the value of pid of the + inferior. CMD is the buffer for command. GDB or GDBserver will store the + command into it and fetch the return result from CMD. The interaction + between GDB/GDBserver and the agent is synchronized by a synchronization + socket. Return zero if success, otherwise return non-zero. */ + +int +agent_run_command (int pid, const char *cmd, int len) +{ + int fd; + int tid = agent_get_helper_thread_id (); + ptid_t ptid = ptid_t (pid, tid, 0); + + int ret = target_write_memory (ipa_sym_addrs.addr_cmd_buf, + (gdb_byte *) cmd, len); + + if (ret != 0) + { + warning (_("unable to write")); + return -1; + } + + DEBUG_AGENT ("agent: resumed helper thread\n"); + + /* Resume helper thread. */ + target_continue_no_signal (ptid); + + fd = gdb_connect_sync_socket (pid); + if (fd >= 0) + { + char buf[1] = ""; + + DEBUG_AGENT ("agent: signalling helper thread\n"); + + do + { + ret = write (fd, buf, 1); + } while (ret == -1 && errno == EINTR); + + DEBUG_AGENT ("agent: waiting for helper thread's response\n"); + + do + { + ret = read (fd, buf, 1); + } while (ret == -1 && errno == EINTR); + + close (fd); + + DEBUG_AGENT ("agent: helper thread's response received\n"); + } + else + return -1; + + /* Need to read response with the inferior stopped. */ + if (ptid != null_ptid) + { + /* Stop thread PTID. */ + DEBUG_AGENT ("agent: stop helper thread\n"); + target_stop_and_wait (ptid); + } + + if (fd >= 0) + { + if (target_read_memory (ipa_sym_addrs.addr_cmd_buf, (gdb_byte *) cmd, + IPA_CMD_BUF_SIZE)) + { + warning (_("Error reading command response")); + return -1; + } + } + + return 0; +} + +/* Each bit of it stands for a capability of agent. */ +static uint32_t agent_capability = 0; + +/* Return true if agent has capability AGENT_CAP, otherwise return false. */ + +bool +agent_capability_check (enum agent_capa agent_capa) +{ + if (agent_capability == 0) + { + if (target_read_uint32 (ipa_sym_addrs.addr_capability, + &agent_capability)) + warning (_("Error reading capability of agent")); + } + return (agent_capability & agent_capa) != 0; +} + +/* Invalidate the cache of agent capability, so we'll read it from inferior + again. Call it when launches a new program or reconnect to remote stub. */ + +void +agent_capability_invalidate (void) +{ + agent_capability = 0; +} diff --git a/gdbsupport/agent.h b/gdbsupport/agent.h new file mode 100644 index 0000000..cc52fb6 --- /dev/null +++ b/gdbsupport/agent.h @@ -0,0 +1,68 @@ +/* Shared utility routines for GDB to interact with agent. + + Copyright (C) 2009-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_AGENT_H +#define COMMON_AGENT_H + +#include "gdbsupport/preprocessor.h" + +int agent_run_command (int pid, const char *cmd, int len); + +int agent_look_up_symbols (void *); + +#define IPA_SYM_EXPORTED_NAME(SYM) gdb_agent_ ## SYM + +/* Define an entry in an IPA symbol list array. If IPA_SYM is used, the macro + IPA_SYM_STRUCT_NAME must be defined to the structure name holding the IPA + symbol addresses in that particular file, before including + gdbsupport/agent.h. */ +#define IPA_SYM(SYM) \ + { \ + STRINGIFY (IPA_SYM_EXPORTED_NAME (SYM)), \ + offsetof (IPA_SYM_STRUCT_NAME, addr_ ## SYM) \ + } + +/* The size in bytes of the buffer used to talk to the IPA helper + thread. */ +#define IPA_CMD_BUF_SIZE 1024 + +bool agent_loaded_p (void); + +extern bool debug_agent; + +extern bool use_agent; + +/* Capability of agent. Different agents may have different capabilities, + such as installing fast tracepoint or evaluating breakpoint conditions. + Capabilities are represented by bit-maps, and each capability occupies one + bit. */ + +enum agent_capa +{ + /* Capability to install fast tracepoint. */ + AGENT_CAPA_FAST_TRACE = 0x1, + /* Capability to install static tracepoint. */ + AGENT_CAPA_STATIC_TRACE = (0x1 << 1), +}; + +bool agent_capability_check (enum agent_capa); + +void agent_capability_invalidate (void); + +#endif /* COMMON_AGENT_H */ diff --git a/gdbsupport/alt-stack.h b/gdbsupport/alt-stack.h new file mode 100644 index 0000000..e7c6b2f --- /dev/null +++ b/gdbsupport/alt-stack.h @@ -0,0 +1,70 @@ +/* Temporarily install an alternate signal stack + + Copyright (C) 2019-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef GDBSUPPORT_ALT_STACK_H +#define GDBSUPPORT_ALT_STACK_H + +#include <signal.h> + +namespace gdb +{ + +/* Try to set up an alternate signal stack for SIGSEGV handlers. + This allows us to handle SIGSEGV signals generated when the + normal process stack is exhausted. If this stack is not set + up (sigaltstack is unavailable or fails) and a SIGSEGV is + generated when the normal stack is exhausted then the program + will behave as though no SIGSEGV handler was installed. */ +class alternate_signal_stack +{ +public: + alternate_signal_stack () + { +#ifdef HAVE_SIGALTSTACK + m_stack.reset ((char *) xmalloc (SIGSTKSZ)); + + stack_t stack; + stack.ss_sp = m_stack.get (); + stack.ss_size = SIGSTKSZ; + stack.ss_flags = 0; + + sigaltstack (&stack, &m_old_stack); +#endif + } + + ~alternate_signal_stack () + { +#ifdef HAVE_SIGALTSTACK + sigaltstack (&m_old_stack, nullptr); +#endif + } + + DISABLE_COPY_AND_ASSIGN (alternate_signal_stack); + +private: + +#ifdef HAVE_SIGALTSTACK + gdb::unique_xmalloc_ptr<char> m_stack; + stack_t m_old_stack; +#endif +}; + +} + +#endif /* GDBSUPPORT_ALT_STACK_H */ diff --git a/gdbsupport/array-view.h b/gdbsupport/array-view.h new file mode 100644 index 0000000..ed5edc7 --- /dev/null +++ b/gdbsupport/array-view.h @@ -0,0 +1,259 @@ +/* Copyright (C) 2017-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_ARRAY_VIEW_H +#define COMMON_ARRAY_VIEW_H + +#include "traits.h" +#include <type_traits> + +/* An array_view is an abstraction that provides a non-owning view + over a sequence of contiguous objects. + + A way to put it is that array_view is to std::vector (and + std::array and built-in arrays with rank==1) like std::string_view + is to std::string. + + The main intent of array_view is to use it as function input + parameter type, making it possible to pass in any sequence of + contiguous objects, irrespective of whether the objects live on the + stack or heap and what actual container owns them. Implicit + construction from the element type is supported too, making it easy + to call functions that expect an array of elements when you only + have one element (usually on the stack). For example: + + struct A { .... }; + void function (gdb::array_view<A> as); + + std::vector<A> std_vec = ...; + std::array<A, N> std_array = ...; + A array[] = {...}; + A elem; + + function (std_vec); + function (std_array); + function (array); + function (elem); + + Views can be either mutable or const. A const view is simply + created by specifying a const T as array_view template parameter, + in which case operator[] of non-const array_view objects ends up + returning const references. Making the array_view itself const is + analogous to making a pointer itself be const. I.e., disables + re-seating the view/pointer. + + Since array_view objects are small (pointer plus size), and + designed to be trivially copyable, they should generally be passed + around by value. + + You can find unit tests covering the whole API in + unittests/array-view-selftests.c. */ + +namespace gdb { + +template <typename T> +class array_view +{ + /* True iff decayed T is the same as decayed U. E.g., we want to + say that 'T&' is the same as 'const T'. */ + template <typename U> + using IsDecayedT = typename std::is_same<typename std::decay<T>::type, + typename std::decay<U>::type>; + + /* True iff decayed T is the same as decayed U, and 'U *' is + implicitly convertible to 'T *'. This is a requirement for + several methods. */ + template <typename U> + using DecayedConvertible = gdb::And<IsDecayedT<U>, + std::is_convertible<U *, T *>>; + +public: + using value_type = T; + using reference = T &; + using const_reference = const T &; + using size_type = size_t; + + /* Default construction creates an empty view. */ + constexpr array_view () noexcept + : m_array (nullptr), m_size (0) + {} + + /* Create an array view over a single object of the type of an + array_view element. The created view as size==1. This is + templated on U to allow constructing a array_view<const T> over a + (non-const) T. The "convertible" requirement makes sure that you + can't create an array_view<T> over a const T. */ + template<typename U, + typename = Requires<DecayedConvertible<U>>> + constexpr array_view (U &elem) noexcept + : m_array (&elem), m_size (1) + {} + + /* Same as above, for rvalue references. */ + template<typename U, + typename = Requires<DecayedConvertible<U>>> + constexpr array_view (U &&elem) noexcept + : m_array (&elem), m_size (1) + {} + + /* Create an array view from a pointer to an array and an element + count. */ + template<typename U, + typename = Requires<DecayedConvertible<U>>> + constexpr array_view (U *array, size_t size) noexcept + : m_array (array), m_size (size) + {} + + /* Create an array view from a range. This is templated on both U + an V to allow passing in a mix of 'const T *' and 'T *'. */ + template<typename U, typename V, + typename = Requires<DecayedConvertible<U>>, + typename = Requires<DecayedConvertible<V>>> + constexpr array_view (U *begin, V *end) noexcept + : m_array (begin), m_size (end - begin) + {} + + /* Create an array view from an array. */ + template<typename U, size_t Size, + typename = Requires<DecayedConvertible<U>>> + constexpr array_view (U (&array)[Size]) noexcept + : m_array (array), m_size (Size) + {} + + /* Create an array view from a contiguous container. E.g., + std::vector and std::array. */ + template<typename Container, + typename = Requires<gdb::Not<IsDecayedT<Container>>>, + typename + = Requires<std::is_convertible + <decltype (std::declval<Container> ().data ()), + T *>>, + typename + = Requires<std::is_convertible + <decltype (std::declval<Container> ().size ()), + size_type>>> + constexpr array_view (Container &&c) noexcept + : m_array (c.data ()), m_size (c.size ()) + {} + + /* Observer methods. Some of these can't be constexpr until we + require C++14. */ + /*constexpr14*/ T *data () noexcept { return m_array; } + constexpr const T *data () const noexcept { return m_array; } + + /*constexpr14*/ T *begin () noexcept { return m_array; } + constexpr const T *begin () const noexcept { return m_array; } + + /*constexpr14*/ T *end () noexcept { return m_array + m_size; } + constexpr const T *end () const noexcept { return m_array + m_size; } + + /*constexpr14*/ reference operator[] (size_t index) noexcept + { return m_array[index]; } + constexpr const_reference operator[] (size_t index) const noexcept + { return m_array[index]; } + + constexpr size_type size () const noexcept { return m_size; } + constexpr bool empty () const noexcept { return m_size == 0; } + + /* Slice an array view. */ + + /* Return a new array view over SIZE elements starting at START. */ + constexpr array_view<T> slice (size_type start, size_type size) const noexcept + { return {m_array + start, size}; } + + /* Return a new array view over all the elements after START, + inclusive. */ + constexpr array_view<T> slice (size_type start) const noexcept + { return {m_array + start, size () - start}; } + +private: + T *m_array; + size_type m_size; +}; + +/* Compare LHS and RHS for (deep) equality. That is, whether LHS and + RHS have the same sizes, and whether each pair of elements of LHS + and RHS at the same position compares equal. */ + +template <typename T> +bool +operator== (const gdb::array_view<T> &lhs, const gdb::array_view<T> &rhs) +{ + if (lhs.size () != rhs.size ()) + return false; + + for (size_t i = 0; i < lhs.size (); i++) + if (!(lhs[i] == rhs[i])) + return false; + + return true; +} + +/* Compare two array_views for inequality. */ + +template <typename T> +bool +operator!= (const gdb::array_view<T> &lhs, const gdb::array_view<T> &rhs) +{ + return !(lhs == rhs); +} + +/* Create an array view from a pointer to an array and an element + count. + + This is useful as alternative to constructing an array_view using + brace initialization when the size variable you have handy is of + signed type, since otherwise without an explicit cast the code + would be ill-formed. + + For example, with: + + extern void foo (int, int, gdb::array_view<value *>); + + value *args[2]; + int nargs; + foo (1, 2, {values, nargs}); + + You'd get: + + source.c:10: error: narrowing conversion of ‘nargs’ from ‘int’ to + ‘size_t {aka long unsigned int}’ inside { } [-Werror=narrowing] + + You could fix it by writing the somewhat distracting explicit cast: + + foo (1, 2, {values, (size_t) nargs}); + + Or by instantiating an array_view explicitly: + + foo (1, 2, gdb::array_view<value *>(values, nargs)); + + Or, better, using make_array_view, which has the advantage of + inferring the arrav_view element's type: + + foo (1, 2, gdb::make_array_view (values, nargs)); +*/ + +template<typename U> +constexpr inline array_view<U> +make_array_view (U *array, size_t size) noexcept +{ + return {array, size}; +} + +} /* namespace gdb */ + +#endif diff --git a/gdbsupport/ax.def b/gdbsupport/ax.def new file mode 100644 index 0000000..3bb6686 --- /dev/null +++ b/gdbsupport/ax.def @@ -0,0 +1,97 @@ +/* Definition of agent opcode values. -*- c -*- + Copyright (C) 1998-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +/* The actual values of the various bytecode operations. + + Other independent implementations of the agent bytecode engine will + rely on the exact values of these enums, and may not be recompiled + when we change this table. The numeric values should remain fixed + whenever possible. Thus, we assign them values explicitly here (to + allow gaps to form safely), and the disassembly table in + agentexpr.h behaves like an opcode map. If you want to see them + grouped logically, see doc/agentexpr.texi. + + Each line is of the form: + + DEFOP (name, size, data_size, consumed, produced, opcode) + + NAME is the name of the operation. + SIZE is the number of argument bytes that the operation takes from + the bytecode stream. + DATA_SIZE is the size of data operated on, in bits, for operations + that care (ref and const). It is zero otherwise. + CONSUMED is the number of stack elements consumed. + PRODUCED is the number of stack elements produced. + OPCODE is the operation's encoding. */ + +DEFOP (float, 0, 0, 0, 0, 0x01) +DEFOP (add, 0, 0, 2, 1, 0x02) +DEFOP (sub, 0, 0, 2, 1, 0x03) +DEFOP (mul, 0, 0, 2, 1, 0x04) +DEFOP (div_signed, 0, 0, 2, 1, 0x05) +DEFOP (div_unsigned, 0, 0, 2, 1, 0x06) +DEFOP (rem_signed, 0, 0, 2, 1, 0x07) +DEFOP (rem_unsigned, 0, 0, 2, 1, 0x08) +DEFOP (lsh, 0, 0, 2, 1, 0x09) +DEFOP (rsh_signed, 0, 0, 2, 1, 0x0a) +DEFOP (rsh_unsigned, 0, 0, 2, 1, 0x0b) +DEFOP (trace, 0, 0, 2, 0, 0x0c) +DEFOP (trace_quick, 1, 0, 1, 1, 0x0d) +DEFOP (log_not, 0, 0, 1, 1, 0x0e) +DEFOP (bit_and, 0, 0, 2, 1, 0x0f) +DEFOP (bit_or, 0, 0, 2, 1, 0x10) +DEFOP (bit_xor, 0, 0, 2, 1, 0x11) +DEFOP (bit_not, 0, 0, 1, 1, 0x12) +DEFOP (equal, 0, 0, 2, 1, 0x13) +DEFOP (less_signed, 0, 0, 2, 1, 0x14) +DEFOP (less_unsigned, 0, 0, 2, 1, 0x15) +DEFOP (ext, 1, 0, 1, 1, 0x16) +DEFOP (ref8, 0, 8, 1, 1, 0x17) +DEFOP (ref16, 0, 16, 1, 1, 0x18) +DEFOP (ref32, 0, 32, 1, 1, 0x19) +DEFOP (ref64, 0, 64, 1, 1, 0x1a) +DEFOP (ref_float, 0, 0, 1, 1, 0x1b) +DEFOP (ref_double, 0, 0, 1, 1, 0x1c) +DEFOP (ref_long_double, 0, 0, 1, 1, 0x1d) +DEFOP (l_to_d, 0, 0, 1, 1, 0x1e) +DEFOP (d_to_l, 0, 0, 1, 1, 0x1f) +DEFOP (if_goto, 2, 0, 1, 0, 0x20) +DEFOP (goto, 2, 0, 0, 0, 0x21) +DEFOP (const8, 1, 8, 0, 1, 0x22) +DEFOP (const16, 2, 16, 0, 1, 0x23) +DEFOP (const32, 4, 32, 0, 1, 0x24) +DEFOP (const64, 8, 64, 0, 1, 0x25) +DEFOP (reg, 2, 0, 0, 1, 0x26) +DEFOP (end, 0, 0, 0, 0, 0x27) +DEFOP (dup, 0, 0, 1, 2, 0x28) +DEFOP (pop, 0, 0, 1, 0, 0x29) +DEFOP (zero_ext, 1, 0, 1, 1, 0x2a) +DEFOP (swap, 0, 0, 2, 2, 0x2b) +DEFOP (getv, 2, 0, 0, 1, 0x2c) +DEFOP (setv, 2, 0, 1, 1, 0x2d) +DEFOP (tracev, 2, 0, 0, 1, 0x2e) +DEFOP (tracenz, 0, 0, 2, 0, 0x2f) +DEFOP (trace16, 2, 0, 1, 1, 0x30) +/* We need something here just to make the tables come out ok. */ +DEFOP (invalid2, 0, 0, 0, 0, 0x31) +/* The "consumed" number for pick is wrong, but there's no way to + express the right thing. */ +DEFOP (pick, 1, 0, 0, 1, 0x32) +DEFOP (rot, 0, 0, 3, 3, 0x33) +/* Both the argument and consumed numbers are dynamic for this one. */ +DEFOP (printf, 0, 0, 0, 0, 0x34) diff --git a/gdbsupport/block-signals.h b/gdbsupport/block-signals.h new file mode 100644 index 0000000..24c971f --- /dev/null +++ b/gdbsupport/block-signals.h @@ -0,0 +1,67 @@ +/* Block signals used by gdb + + Copyright (C) 2019-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef GDBSUPPORT_BLOCK_SIGNALS_H +#define GDBSUPPORT_BLOCK_SIGNALS_H + +#include <signal.h> + +#include "gdbsupport/gdb-sigmask.h" + +namespace gdb +{ + +/* This is an RAII class that temporarily blocks the signals needed by + gdb. This can be used before starting a new thread to ensure that + this thread starts with the appropriate signals blocked. */ +class block_signals +{ +public: + block_signals () + { +#ifdef HAVE_SIGPROCMASK + sigset_t mask; + sigemptyset (&mask); + sigaddset (&mask, SIGINT); + sigaddset (&mask, SIGCHLD); + sigaddset (&mask, SIGALRM); + sigaddset (&mask, SIGWINCH); + gdb_sigmask (SIG_BLOCK, &mask, &m_old_mask); +#endif + } + + ~block_signals () + { +#ifdef HAVE_SIGPROCMASK + gdb_sigmask (SIG_SETMASK, &m_old_mask, nullptr); +#endif + } + + DISABLE_COPY_AND_ASSIGN (block_signals); + +private: + +#ifdef HAVE_SIGPROCMASK + sigset_t m_old_mask; +#endif +}; + +} + +#endif /* GDBSUPPORT_BLOCK_SIGNALS_H */ diff --git a/gdbsupport/break-common.h b/gdbsupport/break-common.h new file mode 100644 index 0000000..f62383b --- /dev/null +++ b/gdbsupport/break-common.h @@ -0,0 +1,31 @@ +/* Data structures associated with breakpoints shared in both GDB and + GDBserver. + Copyright (C) 1992-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_BREAK_COMMON_H +#define COMMON_BREAK_COMMON_H + +enum target_hw_bp_type + { + hw_write = 0, /* Common HW watchpoint */ + hw_read = 1, /* Read HW watchpoint */ + hw_access = 2, /* Access HW watchpoint */ + hw_execute = 3 /* Execute HW breakpoint */ + }; + +#endif /* COMMON_BREAK_COMMON_H */ diff --git a/gdbsupport/btrace-common.c b/gdbsupport/btrace-common.c new file mode 100644 index 0000000..7d4f642 --- /dev/null +++ b/gdbsupport/btrace-common.c @@ -0,0 +1,190 @@ +/* Copyright (C) 2014-2020 Free Software Foundation, Inc. + + Contributed by Intel Corp. <markus.t.metzger@intel.com> + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "common-defs.h" +#include "btrace-common.h" + + +/* See btrace-common.h. */ + +const char * +btrace_format_string (enum btrace_format format) +{ + switch (format) + { + case BTRACE_FORMAT_NONE: + return _("No or unknown format"); + + case BTRACE_FORMAT_BTS: + return _("Branch Trace Store"); + + case BTRACE_FORMAT_PT: + return _("Intel Processor Trace"); + } + + internal_error (__FILE__, __LINE__, _("Unknown branch trace format")); +} + +/* See btrace-common.h. */ + +const char * +btrace_format_short_string (enum btrace_format format) +{ + switch (format) + { + case BTRACE_FORMAT_NONE: + return "unknown"; + + case BTRACE_FORMAT_BTS: + return "bts"; + + case BTRACE_FORMAT_PT: + return "pt"; + } + + internal_error (__FILE__, __LINE__, _("Unknown branch trace format")); +} + +/* See btrace-common.h. */ + +void +btrace_data::fini () +{ + switch (format) + { + case BTRACE_FORMAT_NONE: + /* Nothing to do. */ + return; + + case BTRACE_FORMAT_BTS: + delete variant.bts.blocks; + variant.bts.blocks = nullptr; + return; + + case BTRACE_FORMAT_PT: + xfree (variant.pt.data); + return; + } + + internal_error (__FILE__, __LINE__, _("Unkown branch trace format.")); +} + +/* See btrace-common.h. */ + +bool +btrace_data::empty () const +{ + switch (format) + { + case BTRACE_FORMAT_NONE: + return true; + + case BTRACE_FORMAT_BTS: + return variant.bts.blocks->empty (); + + case BTRACE_FORMAT_PT: + return (variant.pt.size == 0); + } + + internal_error (__FILE__, __LINE__, _("Unkown branch trace format.")); +} + +/* See btrace-common.h. */ + +void +btrace_data::clear () +{ + fini (); + format = BTRACE_FORMAT_NONE; +} + +/* See btrace-common.h. */ + +int +btrace_data_append (struct btrace_data *dst, + const struct btrace_data *src) +{ + switch (src->format) + { + case BTRACE_FORMAT_NONE: + return 0; + + case BTRACE_FORMAT_BTS: + switch (dst->format) + { + default: + return -1; + + case BTRACE_FORMAT_NONE: + dst->format = BTRACE_FORMAT_BTS; + dst->variant.bts.blocks = new std::vector<btrace_block>; + + /* Fall-through. */ + case BTRACE_FORMAT_BTS: + { + unsigned int blk; + + /* We copy blocks in reverse order to have the oldest block at + index zero. */ + blk = src->variant.bts.blocks->size (); + while (blk != 0) + { + const btrace_block &block + = src->variant.bts.blocks->at (--blk); + dst->variant.bts.blocks->push_back (block); + } + } + } + return 0; + + case BTRACE_FORMAT_PT: + switch (dst->format) + { + default: + return -1; + + case BTRACE_FORMAT_NONE: + dst->format = BTRACE_FORMAT_PT; + dst->variant.pt.data = NULL; + dst->variant.pt.size = 0; + + /* fall-through. */ + case BTRACE_FORMAT_PT: + { + gdb_byte *data; + size_t size; + + size = src->variant.pt.size + dst->variant.pt.size; + data = (gdb_byte *) xmalloc (size); + + memcpy (data, dst->variant.pt.data, dst->variant.pt.size); + memcpy (data + dst->variant.pt.size, src->variant.pt.data, + src->variant.pt.size); + + xfree (dst->variant.pt.data); + + dst->variant.pt.data = data; + dst->variant.pt.size = size; + } + } + return 0; + } + + internal_error (__FILE__, __LINE__, _("Unkown branch trace format.")); +} diff --git a/gdbsupport/btrace-common.h b/gdbsupport/btrace-common.h new file mode 100644 index 0000000..c9dc683 --- /dev/null +++ b/gdbsupport/btrace-common.h @@ -0,0 +1,260 @@ +/* Branch trace support for GDB, the GNU debugger. + + Copyright (C) 2013-2020 Free Software Foundation, Inc. + + Contributed by Intel Corp. <markus.t.metzger@intel.com>. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_BTRACE_COMMON_H +#define COMMON_BTRACE_COMMON_H + +/* Branch tracing (btrace) is a per-thread control-flow execution trace of the + inferior. For presentation purposes, the branch trace is represented as a + list of sequential control-flow blocks, one such list per thread. */ + +/* A branch trace block. + + This represents a block of sequential control-flow. Adjacent blocks will be + connected via calls, returns, or jumps. The latter can be direct or + indirect, conditional or unconditional. Branches can further be + asynchronous, e.g. interrupts. */ +struct btrace_block +{ + /* The address of the first byte of the first instruction in the block. + The address may be zero if we do not know the beginning of this block, + such as for the first block in a delta trace. */ + CORE_ADDR begin; + + /* The address of the first byte of the last instruction in the block. */ + CORE_ADDR end; + + /* Simple constructor. */ + btrace_block (CORE_ADDR begin, CORE_ADDR end) + : begin (begin), + end (end) + { + /* Nothing. */ + } +}; + +/* Enumeration of btrace formats. */ + +enum btrace_format +{ + /* No branch trace format. */ + BTRACE_FORMAT_NONE, + + /* Branch trace is in Branch Trace Store (BTS) format. + Actually, the format is a sequence of blocks derived from BTS. */ + BTRACE_FORMAT_BTS, + + /* Branch trace is in Intel Processor Trace format. */ + BTRACE_FORMAT_PT +}; + +/* An enumeration of cpu vendors. */ + +enum btrace_cpu_vendor +{ + /* We do not know this vendor. */ + CV_UNKNOWN, + + /* Intel. */ + CV_INTEL +}; + +/* A cpu identifier. */ + +struct btrace_cpu +{ + /* The processor vendor. */ + enum btrace_cpu_vendor vendor; + + /* The cpu family. */ + unsigned short family; + + /* The cpu model. */ + unsigned char model; + + /* The cpu stepping. */ + unsigned char stepping; +}; + +/* A BTS configuration. */ + +struct btrace_config_bts +{ + /* The size of the branch trace buffer in bytes. + + This is unsigned int and not size_t since it is registered as + control variable for "set record btrace bts buffer-size". */ + unsigned int size; +}; + +/* An Intel Processor Trace configuration. */ + +struct btrace_config_pt +{ + /* The size of the branch trace buffer in bytes. + + This is unsigned int and not size_t since it is registered as + control variable for "set record btrace pt buffer-size". */ + unsigned int size; +}; + +/* A branch tracing configuration. + + This describes the requested configuration as well as the actually + obtained configuration. + We describe the configuration for all different formats so we can + easily switch between formats. */ + +struct btrace_config +{ + /* The branch tracing format. */ + enum btrace_format format; + + /* The BTS format configuration. */ + struct btrace_config_bts bts; + + /* The Intel Processor Trace format configuration. */ + struct btrace_config_pt pt; +}; + +/* Branch trace in BTS format. */ +struct btrace_data_bts +{ + /* Branch trace is represented as a vector of branch trace blocks starting + with the most recent block. This needs to be a pointer as we place + btrace_data_bts into a union. */ + std::vector<btrace_block> *blocks; +}; + +/* Configuration information to go with the trace data. */ +struct btrace_data_pt_config +{ + /* The processor on which the trace has been collected. */ + struct btrace_cpu cpu; +}; + +/* Branch trace in Intel Processor Trace format. */ +struct btrace_data_pt +{ + /* Some configuration information to go with the data. */ + struct btrace_data_pt_config config; + + /* The trace data. */ + gdb_byte *data; + + /* The size of DATA in bytes. */ + size_t size; +}; + +/* The branch trace data. */ +struct btrace_data +{ + btrace_data () = default; + + ~btrace_data () + { + fini (); + } + + btrace_data &operator= (btrace_data &&other) + { + if (this != &other) + { + fini (); + format = other.format; + variant = other.variant; + other.format = BTRACE_FORMAT_NONE; + } + return *this; + } + + /* Return true if this is empty; false otherwise. */ + bool empty () const; + + /* Clear this object. */ + void clear (); + + enum btrace_format format = BTRACE_FORMAT_NONE; + + union + { + /* Format == BTRACE_FORMAT_BTS. */ + struct btrace_data_bts bts; + + /* Format == BTRACE_FORMAT_PT. */ + struct btrace_data_pt pt; + } variant; + +private: + + DISABLE_COPY_AND_ASSIGN (btrace_data); + + void fini (); +}; + +/* Target specific branch trace information. */ +struct btrace_target_info; + +/* Enumeration of btrace read types. */ + +enum btrace_read_type +{ + /* Send all available trace. */ + BTRACE_READ_ALL, + + /* Send all available trace, if it changed. */ + BTRACE_READ_NEW, + + /* Send the trace since the last request. This will fail if the trace + buffer overflowed. */ + BTRACE_READ_DELTA +}; + +/* Enumeration of btrace errors. */ + +enum btrace_error +{ + /* No error. Everything is OK. */ + BTRACE_ERR_NONE, + + /* An unknown error. */ + BTRACE_ERR_UNKNOWN, + + /* Branch tracing is not supported on this system. */ + BTRACE_ERR_NOT_SUPPORTED, + + /* The branch trace buffer overflowed; no delta read possible. */ + BTRACE_ERR_OVERFLOW +}; + +/* Return a string representation of FORMAT. */ +extern const char *btrace_format_string (enum btrace_format format); + +/* Return an abbreviation string representation of FORMAT. */ +extern const char *btrace_format_short_string (enum btrace_format format); + +/* Append the branch trace data from SRC to the end of DST. + Both SRC and DST must use the same format. + Returns zero on success; a negative number otherwise. */ +extern int btrace_data_append (struct btrace_data *dst, + const struct btrace_data *src); + +#endif /* COMMON_BTRACE_COMMON_H */ diff --git a/gdbsupport/buffer.c b/gdbsupport/buffer.c new file mode 100644 index 0000000..e3d0f1e --- /dev/null +++ b/gdbsupport/buffer.c @@ -0,0 +1,178 @@ +/* A simple growing buffer for GDB. + + Copyright (C) 2009-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "common-defs.h" +#include "xml-utils.h" +#include "buffer.h" +#include "inttypes.h" +void +buffer_grow (struct buffer *buffer, const char *data, size_t size) +{ + char *new_buffer; + size_t new_buffer_size; + + if (size == 0) + return; + + new_buffer_size = buffer->buffer_size; + + if (new_buffer_size == 0) + new_buffer_size = 1; + + while (buffer->used_size + size > new_buffer_size) + new_buffer_size *= 2; + new_buffer = (char *) xrealloc (buffer->buffer, new_buffer_size); + memcpy (new_buffer + buffer->used_size, data, size); + buffer->buffer = new_buffer; + buffer->buffer_size = new_buffer_size; + buffer->used_size += size; +} + +void +buffer_free (struct buffer *buffer) +{ + if (!buffer) + return; + + xfree (buffer->buffer); + buffer->buffer = NULL; + buffer->buffer_size = 0; + buffer->used_size = 0; +} + +void +buffer_init (struct buffer *buffer) +{ + memset (buffer, 0, sizeof (*buffer)); +} + +char* +buffer_finish (struct buffer *buffer) +{ + char *ret = buffer->buffer; + buffer->buffer = NULL; + buffer->buffer_size = 0; + buffer->used_size = 0; + return ret; +} + +void +buffer_xml_printf (struct buffer *buffer, const char *format, ...) +{ + va_list ap; + const char *f; + const char *prev; + int percent = 0; + + va_start (ap, format); + + prev = format; + for (f = format; *f; f++) + { + if (percent) + { + char buf[32]; + char *str = buf; + const char *f_old = f; + + switch (*f) + { + case 's': + str = va_arg (ap, char *); + break; + case 'd': + sprintf (str, "%d", va_arg (ap, int)); + break; + case 'u': + sprintf (str, "%u", va_arg (ap, unsigned int)); + break; + case 'x': + sprintf (str, "%x", va_arg (ap, unsigned int)); + break; + case 'o': + sprintf (str, "%o", va_arg (ap, unsigned int)); + break; + case 'l': + f++; + switch (*f) + { + case 'd': + sprintf (str, "%ld", va_arg (ap, long)); + break; + case 'u': + sprintf (str, "%lu", va_arg (ap, unsigned long)); + break; + case 'x': + sprintf (str, "%lx", va_arg (ap, unsigned long)); + break; + case 'o': + sprintf (str, "%lo", va_arg (ap, unsigned long)); + break; + case 'l': + f++; + switch (*f) + { + case 'd': + sprintf (str, "%" PRId64, + (int64_t) va_arg (ap, long long)); + break; + case 'u': + sprintf (str, "%" PRIu64, + (uint64_t) va_arg (ap, unsigned long long)); + break; + case 'x': + sprintf (str, "%" PRIx64, + (uint64_t) va_arg (ap, unsigned long long)); + break; + case 'o': + sprintf (str, "%" PRIo64, + (uint64_t) va_arg (ap, unsigned long long)); + break; + default: + str = 0; + break; + } + break; + default: + str = 0; + break; + } + break; + default: + str = 0; + break; + } + + if (str) + { + buffer_grow (buffer, prev, f_old - prev - 1); + std::string p = xml_escape_text (str); + buffer_grow_str (buffer, p.c_str ()); + prev = f + 1; + } + percent = 0; + } + else if (*f == '%') + percent = 1; + } + + buffer_grow_str (buffer, prev); + va_end (ap); +} + diff --git a/gdbsupport/buffer.h b/gdbsupport/buffer.h new file mode 100644 index 0000000..6e4c167 --- /dev/null +++ b/gdbsupport/buffer.h @@ -0,0 +1,68 @@ +/* A simple growing buffer for GDB. + + Copyright (C) 2009-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_BUFFER_H +#define COMMON_BUFFER_H + +struct buffer +{ + char *buffer; + size_t buffer_size; /* allocated size */ + size_t used_size; /* actually used size */ +}; + +/* Append DATA of size SIZE to the end of BUFFER. Grows the buffer to + accommodate the new data. */ +void buffer_grow (struct buffer *buffer, const char *data, size_t size); + +/* Append C to the end of BUFFER. Grows the buffer to accommodate the + new data. */ + +static inline void +buffer_grow_char (struct buffer *buffer, char c) +{ + buffer_grow (buffer, &c, 1); +} + +/* Release any memory held by BUFFER. */ +void buffer_free (struct buffer *buffer); + +/* Initialize BUFFER. BUFFER holds no memory afterwards. */ +void buffer_init (struct buffer *buffer); + +/* Return a pointer into BUFFER data, effectively transferring + ownership of the buffer memory to the caller. Calling buffer_free + afterwards has no effect on the returned data. */ +char* buffer_finish (struct buffer *buffer); + +/* Simple printf to buffer function. Current implemented formatters: + %s - grow an xml escaped text in BUFFER. + %d - grow an signed integer in BUFFER. + %u - grow an unsigned integer in BUFFER. + %x - grow an unsigned integer formatted in hexadecimal in BUFFER. + %o - grow an unsigned integer formatted in octal in BUFFER. */ +void buffer_xml_printf (struct buffer *buffer, const char *format, ...) + ATTRIBUTE_PRINTF (2, 3); + +#define buffer_grow_str(BUFFER,STRING) \ + buffer_grow (BUFFER, STRING, strlen (STRING)) +#define buffer_grow_str0(BUFFER,STRING) \ + buffer_grow (BUFFER, STRING, strlen (STRING) + 1) + +#endif /* COMMON_BUFFER_H */ diff --git a/gdbsupport/byte-vector.h b/gdbsupport/byte-vector.h new file mode 100644 index 0000000..f1fc0cf --- /dev/null +++ b/gdbsupport/byte-vector.h @@ -0,0 +1,63 @@ +/* Copyright (C) 2017-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_BYTE_VECTOR_H +#define COMMON_BYTE_VECTOR_H + +#include "gdbsupport/def-vector.h" + +namespace gdb { + +/* byte_vector is a gdb_byte std::vector with a custom allocator that + unlike std::vector<gdb_byte> does not zero-initialize new elements + by default when the vector is created/resized. This is what you + usually want when working with byte buffers, since if you're + creating or growing a buffer you'll most surely want to fill it in + with data, in which case zero-initialization would be a + pessimization. For example: + + gdb::byte_vector buf (some_large_size); + fill_with_data (buf.data (), buf.size ()); + + On the odd case you do need zero initialization, then you can still + call the overloads that specify an explicit value, like: + + gdb::byte_vector buf (some_initial_size, 0); + buf.resize (a_bigger_size, 0); + + (Or use std::vector<gdb_byte> instead.) + + Note that unlike std::vector<gdb_byte>, function local + gdb::byte_vector objects constructed with an initial size like: + + gdb::byte_vector buf (some_size); + fill_with_data (buf.data (), buf.size ()); + + usually compile down to the exact same as: + + std::unique_ptr<byte[]> buf (new gdb_byte[some_size]); + fill_with_data (buf.get (), some_size); + + with the former having the advantage of being a bit more readable, + and providing the whole std::vector API, if you end up needing it. +*/ +using byte_vector = gdb::def_vector<gdb_byte>; +using char_vector = gdb::def_vector<char>; + +} /* namespace gdb */ + +#endif /* COMMON_DEF_VECTOR_H */ diff --git a/gdbsupport/cleanups.c b/gdbsupport/cleanups.c new file mode 100644 index 0000000..236bc17 --- /dev/null +++ b/gdbsupport/cleanups.c @@ -0,0 +1,144 @@ +/* Cleanup routines for GDB, the GNU debugger. + + Copyright (C) 1986-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "common-defs.h" +#include "cleanups.h" + +/* The cleanup list records things that have to be undone + if an error happens (descriptors to be closed, memory to be freed, etc.) + Each link in the chain records a function to call and an + argument to give it. + + Use make_cleanup to add an element to the cleanup chain. + Use do_cleanups to do all cleanup actions back to a given + point in the chain. Use discard_cleanups to remove cleanups + from the chain back to a given point, not doing them. + + If the argument is pointer to allocated memory, then you need + to additionally set the 'free_arg' member to a function that will + free that memory. This function will be called both when the cleanup + is executed and when it's discarded. */ + +struct cleanup +{ + struct cleanup *next; + void (*function) (void *); + void (*free_arg) (void *); + void *arg; +}; + +/* Used to mark the end of a cleanup chain. + The value is chosen so that it: + - is non-NULL so that make_cleanup never returns NULL, + - causes a segv if dereferenced + [though this won't catch errors that a value of, say, + ((struct cleanup *) -1) will] + - displays as something useful when printed in gdb. + This is const for a bit of extra robustness. + It is initialized to coax gcc into putting it into .rodata. + All fields are initialized to survive -Wextra. */ +static const struct cleanup sentinel_cleanup = { 0, 0, 0, 0 }; + +/* Handy macro to use when referring to sentinel_cleanup. */ +#define SENTINEL_CLEANUP ((struct cleanup *) &sentinel_cleanup) + +/* Chain of cleanup actions established with make_final_cleanup, + to be executed when gdb exits. */ +static struct cleanup *final_cleanup_chain = SENTINEL_CLEANUP; + +/* Main worker routine to create a cleanup. + PMY_CHAIN is a pointer to either cleanup_chain or final_cleanup_chain. + FUNCTION is the function to call to perform the cleanup. + ARG is passed to FUNCTION when called. + FREE_ARG, if non-NULL, is called after the cleanup is performed. + + The result is a pointer to the previous chain pointer + to be passed later to do_cleanups or discard_cleanups. */ + +static struct cleanup * +make_my_cleanup2 (struct cleanup **pmy_chain, make_cleanup_ftype *function, + void *arg, void (*free_arg) (void *)) +{ + struct cleanup *newobj = XNEW (struct cleanup); + struct cleanup *old_chain = *pmy_chain; + + newobj->next = *pmy_chain; + newobj->function = function; + newobj->free_arg = free_arg; + newobj->arg = arg; + *pmy_chain = newobj; + + gdb_assert (old_chain != NULL); + return old_chain; +} + +/* Worker routine to create a cleanup without a destructor. + PMY_CHAIN is a pointer to either cleanup_chain or final_cleanup_chain. + FUNCTION is the function to call to perform the cleanup. + ARG is passed to FUNCTION when called. + + The result is a pointer to the previous chain pointer + to be passed later to do_cleanups or discard_cleanups. */ + +static struct cleanup * +make_my_cleanup (struct cleanup **pmy_chain, make_cleanup_ftype *function, + void *arg) +{ + return make_my_cleanup2 (pmy_chain, function, arg, NULL); +} + +/* Add a new cleanup to the final cleanup_chain, + and return the previous chain pointer + to be passed later to do_cleanups or discard_cleanups. + Args are FUNCTION to clean up with, and ARG to pass to it. */ + +struct cleanup * +make_final_cleanup (make_cleanup_ftype *function, void *arg) +{ + return make_my_cleanup (&final_cleanup_chain, function, arg); +} + +/* Worker routine to perform cleanups. + PMY_CHAIN is a pointer to either cleanup_chain or final_cleanup_chain. + OLD_CHAIN is the result of a "make" cleanup routine. + Cleanups are performed until we get back to the old end of the chain. */ + +static void +do_my_cleanups (struct cleanup **pmy_chain, + struct cleanup *old_chain) +{ + struct cleanup *ptr; + + while ((ptr = *pmy_chain) != old_chain) + { + *pmy_chain = ptr->next; /* Do this first in case of recursion. */ + (*ptr->function) (ptr->arg); + if (ptr->free_arg) + (*ptr->free_arg) (ptr->arg); + xfree (ptr); + } +} + +/* Discard final cleanups and do the actions they describe. */ + +void +do_final_cleanups () +{ + do_my_cleanups (&final_cleanup_chain, SENTINEL_CLEANUP); +} diff --git a/gdbsupport/cleanups.h b/gdbsupport/cleanups.h new file mode 100644 index 0000000..6c4e388 --- /dev/null +++ b/gdbsupport/cleanups.h @@ -0,0 +1,39 @@ +/* Cleanups. + Copyright (C) 1986-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_CLEANUPS_H +#define COMMON_CLEANUPS_H + +/* Outside of cleanups.c, this is an opaque type. */ +struct cleanup; + +/* NOTE: cagney/2000-03-04: This typedef is strictly for the + make_cleanup function declarations below. Do not use this typedef + as a cast when passing functions into the make_cleanup() code. + Instead either use a bounce function or add a wrapper function. + Calling a f(char*) function with f(void*) is non-portable. */ +typedef void (make_cleanup_ftype) (void *); + +/* Function type for the dtor in make_cleanup_dtor. */ +typedef void (make_cleanup_dtor_ftype) (void *); + +extern struct cleanup *make_final_cleanup (make_cleanup_ftype *, void *); + +extern void do_final_cleanups (); + +#endif /* COMMON_CLEANUPS_H */ diff --git a/gdbsupport/common-debug.c b/gdbsupport/common-debug.c new file mode 100644 index 0000000..d1131a0 --- /dev/null +++ b/gdbsupport/common-debug.c @@ -0,0 +1,37 @@ +/* Debug printing functions. + + Copyright (C) 2014-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "common-defs.h" +#include "common-debug.h" + +/* See gdbsupport/common-debug.h. */ + +bool show_debug_regs; + +/* See gdbsupport/common-debug.h. */ + +void +debug_printf (const char *fmt, ...) +{ + va_list ap; + + va_start (ap, fmt); + debug_vprintf (fmt, ap); + va_end (ap); +} diff --git a/gdbsupport/common-debug.h b/gdbsupport/common-debug.h new file mode 100644 index 0000000..9934ec5 --- /dev/null +++ b/gdbsupport/common-debug.h @@ -0,0 +1,41 @@ +/* Declarations for debug printing functions. + + Copyright (C) 2014-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_COMMON_DEBUG_H +#define COMMON_COMMON_DEBUG_H + +/* Set to true to enable debugging of hardware breakpoint/ + watchpoint support code. */ + +extern bool show_debug_regs; + +/* Print a formatted message to the appropriate channel for + debugging output for the client. */ + +extern void debug_printf (const char *format, ...) + ATTRIBUTE_PRINTF (1, 2); + +/* Print a formatted message to the appropriate channel for + debugging output for the client. This function must be + provided by the client. */ + +extern void debug_vprintf (const char *format, va_list ap) + ATTRIBUTE_PRINTF (1, 0); + +#endif /* COMMON_COMMON_DEBUG_H */ diff --git a/gdbsupport/common-defs.h b/gdbsupport/common-defs.h new file mode 100644 index 0000000..d823c41 --- /dev/null +++ b/gdbsupport/common-defs.h @@ -0,0 +1,162 @@ +/* Common definitions. + + Copyright (C) 1986-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_COMMON_DEFS_H +#define COMMON_COMMON_DEFS_H + +#ifdef GDBSERVER + +#include <build-gnulib-gdbserver/config.h> + +#undef PACKAGE_NAME +#undef PACKAGE +#undef PACKAGE_VERSION +#undef PACKAGE_STRING +#undef PACKAGE_TARNAME + +#include <config.h> + +#else /* GDBSERVER */ + +#include <gdbsupport/support-config.h> + +#undef PACKAGE_NAME +#undef PACKAGE +#undef PACKAGE_VERSION +#undef PACKAGE_STRING +#undef PACKAGE_TARNAME + +#include "gnulib/config.h" + +#endif /* GDBSERVER */ + +/* From: + https://www.gnu.org/software/gnulib/manual/html_node/stdint_002eh.html + + "On some hosts that predate C++11, when using C++ one must define + __STDC_CONSTANT_MACROS to make visible the definitions of constant + macros such as INTMAX_C, and one must define __STDC_LIMIT_MACROS to + make visible the definitions of limit macros such as INTMAX_MAX.". + + And: + https://www.gnu.org/software/gnulib/manual/html_node/inttypes_002eh.html + + "On some hosts that predate C++11, when using C++ one must define + __STDC_FORMAT_MACROS to make visible the declarations of format + macros such as PRIdMAX." + + Must do this before including any system header, since other system + headers may include stdint.h/inttypes.h. */ +#define __STDC_CONSTANT_MACROS 1 +#define __STDC_LIMIT_MACROS 1 +#define __STDC_FORMAT_MACROS 1 + +/* Some distros enable _FORTIFY_SOURCE by default, which on occasion + has caused build failures with -Wunused-result when a patch is + developed on a distro that does not enable _FORTIFY_SOURCE. We + enable it here in order to try to catch these problems earlier; + plus this seems like a reasonable safety measure. The check for + optimization is required because _FORTIFY_SOURCE only works when + optimization is enabled. If _FORTIFY_SOURCE is already defined, + then we don't do anything. Also, on MinGW, fortify requires + linking to -lssp, and to avoid the hassle of checking for + that and linking to it statically, we just don't define + _FORTIFY_SOURCE there. */ + +#if (!defined _FORTIFY_SOURCE && defined __OPTIMIZE__ && __OPTIMIZE__ > 0 \ + && !defined(__MINGW32__)) +#define _FORTIFY_SOURCE 2 +#endif + +/* We don't support Windows versions before XP, so we define + _WIN32_WINNT correspondingly to ensure the Windows API headers + expose the required symbols. */ +#if defined (__MINGW32__) || defined (__CYGWIN__) +# ifdef _WIN32_WINNT +# if _WIN32_WINNT < 0x0501 +# undef _WIN32_WINNT +# define _WIN32_WINNT 0x0501 +# endif +# else +# define _WIN32_WINNT 0x0501 +# endif +#endif /* __MINGW32__ || __CYGWIN__ */ + +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <stddef.h> +#include <stdint.h> +#include <string.h> +#ifdef HAVE_STRINGS_H +#include <strings.h> /* for strcasecmp and strncasecmp */ +#endif +#include <errno.h> +#include <alloca.h> + +#include "ansidecl.h" +/* This is defined by ansidecl.h, but we prefer gnulib's version. On + MinGW, gnulib might enable __USE_MINGW_ANSI_STDIO, which may or not + require use of attribute gnu_printf instead of printf. gnulib + checks that at configure time. Since _GL_ATTRIBUTE_FORMAT_PRINTF + is compatible with ATTRIBUTE_PRINTF, simply use it. */ +#undef ATTRIBUTE_PRINTF +#define ATTRIBUTE_PRINTF _GL_ATTRIBUTE_FORMAT_PRINTF + +#if GCC_VERSION >= 3004 +#define ATTRIBUTE_UNUSED_RESULT __attribute__ ((__warn_unused_result__)) +#else +#define ATTRIBUTE_UNUSED_RESULT +#endif + +#include "libiberty.h" +#include "pathmax.h" +#include "gdb/signals.h" +#include "gdb_locale.h" +#include "ptid.h" +#include "common-types.h" +#include "common-utils.h" +#include "gdb_assert.h" +#include "errors.h" +#include "print-utils.h" +#include "common-debug.h" +#include "cleanups.h" +#include "common-exceptions.h" +#include "gdbsupport/poison.h" + +#define EXTERN_C extern "C" +#define EXTERN_C_PUSH extern "C" { +#define EXTERN_C_POP } + +/* Pull in gdb::unique_xmalloc_ptr. */ +#include "gdbsupport/gdb_unique_ptr.h" + +/* String containing the current directory (what getwd would return). */ +extern char *current_directory; + +/* sbrk on macOS is not useful for our purposes, since sbrk(0) always + returns the same value. brk/sbrk on macOS is just an emulation + that always returns a pointer to a 4MB section reserved for + that. */ + +#if defined (HAVE_SBRK) && !__APPLE__ +#define HAVE_USEFUL_SBRK 1 +#endif + +#endif /* COMMON_COMMON_DEFS_H */ diff --git a/gdbsupport/common-exceptions.c b/gdbsupport/common-exceptions.c new file mode 100644 index 0000000..0cc515b --- /dev/null +++ b/gdbsupport/common-exceptions.c @@ -0,0 +1,235 @@ +/* Exception (throw catch) mechanism, for GDB, the GNU debugger. + + Copyright (C) 1986-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "common-defs.h" +#include "common-exceptions.h" +#include <forward_list> + +/* Possible catcher states. */ +enum catcher_state { + /* Initial state, a new catcher has just been created. */ + CATCHER_CREATED, + /* The catch code is running. */ + CATCHER_RUNNING, + CATCHER_RUNNING_1, + /* The catch code threw an exception. */ + CATCHER_ABORTING +}; + +/* Possible catcher actions. */ +enum catcher_action { + CATCH_ITER, + CATCH_ITER_1, + CATCH_THROWING +}; + +struct catcher +{ + enum catcher_state state = CATCHER_CREATED; + /* Jump buffer pointing back at the exception handler. */ + jmp_buf buf; + /* Status buffer belonging to the exception handler. */ + struct gdb_exception exception; +}; + +/* Where to go for throw_exception(). */ +static std::forward_list<struct catcher> catchers; + +jmp_buf * +exceptions_state_mc_init () +{ + catchers.emplace_front (); + return &catchers.front ().buf; +} + +/* Catcher state machine. Returns non-zero if the m/c should be run + again, zero if it should abort. */ + +static int +exceptions_state_mc (enum catcher_action action) +{ + switch (catchers.front ().state) + { + case CATCHER_CREATED: + switch (action) + { + case CATCH_ITER: + /* Allow the code to run the catcher. */ + catchers.front ().state = CATCHER_RUNNING; + return 1; + default: + internal_error (__FILE__, __LINE__, _("bad state")); + } + case CATCHER_RUNNING: + switch (action) + { + case CATCH_ITER: + /* No error/quit has occured. */ + return 0; + case CATCH_ITER_1: + catchers.front ().state = CATCHER_RUNNING_1; + return 1; + case CATCH_THROWING: + catchers.front ().state = CATCHER_ABORTING; + /* See also throw_exception. */ + return 1; + default: + internal_error (__FILE__, __LINE__, _("bad switch")); + } + case CATCHER_RUNNING_1: + switch (action) + { + case CATCH_ITER: + /* The did a "break" from the inner while loop. */ + return 0; + case CATCH_ITER_1: + catchers.front ().state = CATCHER_RUNNING; + return 0; + case CATCH_THROWING: + catchers.front ().state = CATCHER_ABORTING; + /* See also throw_exception. */ + return 1; + default: + internal_error (__FILE__, __LINE__, _("bad switch")); + } + case CATCHER_ABORTING: + switch (action) + { + case CATCH_ITER: + { + /* Exit normally if this catcher can handle this + exception. The caller analyses the func return + values. */ + return 0; + } + default: + internal_error (__FILE__, __LINE__, _("bad state")); + } + default: + internal_error (__FILE__, __LINE__, _("bad switch")); + } +} + +int +exceptions_state_mc_catch (struct gdb_exception *exception, + int mask) +{ + *exception = std::move (catchers.front ().exception); + catchers.pop_front (); + + if (exception->reason < 0) + { + if (mask & RETURN_MASK (exception->reason)) + { + /* Exit normally and let the caller handle the + exception. */ + return 1; + } + + /* The caller didn't request that the event be caught, relay the + event to the next exception_catch/CATCH_SJLJ. */ + throw_exception_sjlj (*exception); + } + + /* No exception was thrown. */ + return 0; +} + +int +exceptions_state_mc_action_iter (void) +{ + return exceptions_state_mc (CATCH_ITER); +} + +int +exceptions_state_mc_action_iter_1 (void) +{ + return exceptions_state_mc (CATCH_ITER_1); +} + +/* Return EXCEPTION to the nearest containing CATCH_SJLJ block. */ + +void +throw_exception_sjlj (const struct gdb_exception &exception) +{ + /* Jump to the nearest CATCH_SJLJ block, communicating REASON to + that call via setjmp's return value. Note that REASON can't be + zero, by definition in common-exceptions.h. */ + exceptions_state_mc (CATCH_THROWING); + enum return_reason reason = exception.reason; + catchers.front ().exception = exception; + longjmp (catchers.front ().buf, reason); +} + +/* Implementation of throw_exception that uses C++ try/catch. */ + +void +throw_exception (gdb_exception &&exception) +{ + if (exception.reason == RETURN_QUIT) + throw gdb_exception_quit (std::move (exception)); + else if (exception.reason == RETURN_ERROR) + throw gdb_exception_error (std::move (exception)); + else + gdb_assert_not_reached ("invalid return reason"); +} + +static void ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (3, 0) +throw_it (enum return_reason reason, enum errors error, const char *fmt, + va_list ap) +{ + if (reason == RETURN_QUIT) + throw gdb_exception_quit (fmt, ap); + else if (reason == RETURN_ERROR) + throw gdb_exception_error (error, fmt, ap); + else + gdb_assert_not_reached ("invalid return reason"); +} + +void +throw_verror (enum errors error, const char *fmt, va_list ap) +{ + throw_it (RETURN_ERROR, error, fmt, ap); +} + +void +throw_vquit (const char *fmt, va_list ap) +{ + throw_it (RETURN_QUIT, GDB_NO_ERROR, fmt, ap); +} + +void +throw_error (enum errors error, const char *fmt, ...) +{ + va_list args; + + va_start (args, fmt); + throw_verror (error, fmt, args); + va_end (args); +} + +void +throw_quit (const char *fmt, ...) +{ + va_list args; + + va_start (args, fmt); + throw_vquit (fmt, args); + va_end (args); +} diff --git a/gdbsupport/common-exceptions.h b/gdbsupport/common-exceptions.h new file mode 100644 index 0000000..76d916f --- /dev/null +++ b/gdbsupport/common-exceptions.h @@ -0,0 +1,304 @@ +/* Exception (throw catch) mechanism, for GDB, the GNU debugger. + + Copyright (C) 1986-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_COMMON_EXCEPTIONS_H +#define COMMON_COMMON_EXCEPTIONS_H + +#include <setjmp.h> +#include <new> +#include <memory> +#include <string> + +/* Reasons for calling throw_exceptions(). NOTE: all reason values + must be different from zero. enum value 0 is reserved for internal + use as the return value from an initial setjmp(). */ + +enum return_reason + { + /* User interrupt. */ + RETURN_QUIT = -2, + /* Any other error. */ + RETURN_ERROR + }; + +#define RETURN_MASK(reason) (1 << (int)(-reason)) + +typedef enum +{ + RETURN_MASK_QUIT = RETURN_MASK (RETURN_QUIT), + RETURN_MASK_ERROR = RETURN_MASK (RETURN_ERROR), + RETURN_MASK_ALL = (RETURN_MASK_QUIT | RETURN_MASK_ERROR) +} return_mask; + +/* Describe all exceptions. */ + +enum errors { + GDB_NO_ERROR, + + /* Any generic error, the corresponding text is in + exception.message. */ + GENERIC_ERROR, + + /* Something requested was not found. */ + NOT_FOUND_ERROR, + + /* Thread library lacks support necessary for finding thread local + storage. */ + TLS_NO_LIBRARY_SUPPORT_ERROR, + + /* Load module not found while attempting to find thread local storage. */ + TLS_LOAD_MODULE_NOT_FOUND_ERROR, + + /* Thread local storage has not been allocated yet. */ + TLS_NOT_ALLOCATED_YET_ERROR, + + /* Something else went wrong while attempting to find thread local + storage. The ``struct gdb_exception'' message field provides + more detail. */ + TLS_GENERIC_ERROR, + + /* Problem parsing an XML document. */ + XML_PARSE_ERROR, + + /* Error accessing memory. */ + MEMORY_ERROR, + + /* Value not available. E.g., a register was not collected in a + traceframe. */ + NOT_AVAILABLE_ERROR, + + /* Value was optimized out. Note: if the value was a register, this + means the register was not saved in the frame. */ + OPTIMIZED_OUT_ERROR, + + /* DW_OP_entry_value resolving failed. */ + NO_ENTRY_VALUE_ERROR, + + /* Target throwing an error has been closed. Current command should be + aborted as the inferior state is no longer valid. */ + TARGET_CLOSE_ERROR, + + /* An undefined command was executed. */ + UNDEFINED_COMMAND_ERROR, + + /* Requested feature, method, mechanism, etc. is not supported. */ + NOT_SUPPORTED_ERROR, + + /* The number of candidates generated during line completion has + reached the user's specified limit. This isn't an error, this exception + is used to halt searching for more completions, but for consistency + "_ERROR" is appended to the name. */ + MAX_COMPLETIONS_REACHED_ERROR, + + /* Add more errors here. */ + NR_ERRORS +}; + +struct gdb_exception +{ + gdb_exception () + : reason ((enum return_reason) 0), + error (GDB_NO_ERROR) + { + } + + gdb_exception (enum return_reason r, enum errors e) + : reason (r), + error (e) + { + } + + gdb_exception (enum return_reason r, enum errors e, + const char *fmt, va_list ap) + ATTRIBUTE_PRINTF (4, 0) + : reason (r), + error (e), + message (std::make_shared<std::string> (string_vprintf (fmt, ap))) + { + } + + /* The move constructor exists so that we can mark it "noexcept", + which is a good practice for any sort of exception object. */ + explicit gdb_exception (gdb_exception &&other) noexcept = default; + + /* The copy constructor exists so that we can mark it "noexcept", + which is a good practice for any sort of exception object. */ + gdb_exception (const gdb_exception &other) noexcept + : reason (other.reason), + error (other.error), + message (other.message) + { + } + + /* The assignment operator exists so that we can mark it "noexcept", + which is a good practice for any sort of exception object. */ + gdb_exception &operator= (const gdb_exception &other) noexcept + { + reason = other.reason; + error = other.error; + message = other.message; + return *this; + } + + gdb_exception &operator= (gdb_exception &&other) noexcept = default; + + /* Return the contents of the exception message, as a C string. The + string remains owned by the exception object. */ + const char *what () const noexcept + { + return message->c_str (); + } + + enum return_reason reason; + enum errors error; + std::shared_ptr<std::string> message; +}; + +/* Functions to drive the sjlj-based exceptions state machine. Though + declared here by necessity, these functions should be considered + internal to the exceptions subsystem and not used other than via + the TRY/CATCH (or TRY_SJLJ/CATCH_SJLJ) macros defined below. */ + +extern jmp_buf *exceptions_state_mc_init (void); +extern int exceptions_state_mc_action_iter (void); +extern int exceptions_state_mc_action_iter_1 (void); +extern int exceptions_state_mc_catch (struct gdb_exception *, int); + +/* Macro to wrap up standard try/catch behavior. + + The double loop lets us correctly handle code "break"ing out of the + try catch block. (It works as the "break" only exits the inner + "while" loop, the outer for loop detects this handling it + correctly.) Of course "return" and "goto" are not so lucky. + + For instance: + + *INDENT-OFF* + + TRY_SJLJ + { + } + CATCH_SJLJ (e, RETURN_MASK_ERROR) + { + switch (e.reason) + { + case RETURN_ERROR: ... + } + } + END_CATCH_SJLJ + + The SJLJ variants are needed in some cases where gdb exceptions + need to cross third-party library code compiled without exceptions + support (e.g., readline). */ + +#define TRY_SJLJ \ + { \ + jmp_buf *buf = \ + exceptions_state_mc_init (); \ + setjmp (*buf); \ + } \ + while (exceptions_state_mc_action_iter ()) \ + while (exceptions_state_mc_action_iter_1 ()) + +#define CATCH_SJLJ(EXCEPTION, MASK) \ + { \ + struct gdb_exception EXCEPTION; \ + if (exceptions_state_mc_catch (&(EXCEPTION), MASK)) + +#define END_CATCH_SJLJ \ + } + +/* The exception types client code may catch. They're just shims + around gdb_exception that add nothing but type info. Which is used + is selected depending on the MASK argument passed to CATCH. */ + +struct gdb_exception_error : public gdb_exception +{ + gdb_exception_error (enum errors e, const char *fmt, va_list ap) + ATTRIBUTE_PRINTF (3, 0) + : gdb_exception (RETURN_ERROR, e, fmt, ap) + { + } + + explicit gdb_exception_error (gdb_exception &&ex) noexcept + : gdb_exception (std::move (ex)) + { + gdb_assert (ex.reason == RETURN_ERROR); + } +}; + +struct gdb_exception_quit : public gdb_exception +{ + gdb_exception_quit (const char *fmt, va_list ap) + ATTRIBUTE_PRINTF (2, 0) + : gdb_exception (RETURN_QUIT, GDB_NO_ERROR, fmt, ap) + { + } + + explicit gdb_exception_quit (gdb_exception &&ex) noexcept + : gdb_exception (std::move (ex)) + { + gdb_assert (ex.reason == RETURN_QUIT); + } +}; + +/* An exception type that inherits from both std::bad_alloc and a gdb + exception. This is necessary because operator new can only throw + std::bad_alloc, and OTOH, we want exceptions thrown due to memory + allocation error to be caught by all the CATCH/RETURN_MASK_ALL + spread around the codebase. */ + +struct gdb_quit_bad_alloc + : public gdb_exception_quit, + public std::bad_alloc +{ + explicit gdb_quit_bad_alloc (gdb_exception &&ex) noexcept + : gdb_exception_quit (std::move (ex)), + std::bad_alloc () + { + } +}; + +/* *INDENT-ON* */ + +/* Throw an exception (as described by "struct gdb_exception"), + landing in the inner most containing exception handler established + using TRY/CATCH. */ +extern void throw_exception (gdb_exception &&exception) + ATTRIBUTE_NORETURN; + +/* Throw an exception by executing a LONG JUMP to the inner most + containing exception handler established using TRY_SJLJ. Necessary + in some cases where we need to throw GDB exceptions across + third-party library code (e.g., readline). */ +extern void throw_exception_sjlj (const struct gdb_exception &exception) + ATTRIBUTE_NORETURN; + +/* Convenience wrappers around throw_exception that throw GDB + errors. */ +extern void throw_verror (enum errors, const char *fmt, va_list ap) + ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (2, 0); +extern void throw_vquit (const char *fmt, va_list ap) + ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (1, 0); +extern void throw_error (enum errors error, const char *fmt, ...) + ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (2, 3); +extern void throw_quit (const char *fmt, ...) + ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (1, 2); + +#endif /* COMMON_COMMON_EXCEPTIONS_H */ diff --git a/gdbsupport/common-gdbthread.h b/gdbsupport/common-gdbthread.h new file mode 100644 index 0000000..050ad80 --- /dev/null +++ b/gdbsupport/common-gdbthread.h @@ -0,0 +1,28 @@ +/* Common multi-process/thread control defs for GDB and gdbserver. + Copyright (C) 1987-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_COMMON_GDBTHREAD_H +#define COMMON_COMMON_GDBTHREAD_H + +struct process_stratum_target; + +/* Switch from one thread to another. */ +extern void switch_to_thread (process_stratum_target *proc_target, + ptid_t ptid); + +#endif /* COMMON_COMMON_GDBTHREAD_H */ diff --git a/gdbsupport/common-inferior.c b/gdbsupport/common-inferior.c new file mode 100644 index 0000000..ed16e89 --- /dev/null +++ b/gdbsupport/common-inferior.c @@ -0,0 +1,26 @@ +/* Functions to deal with the inferior being executed on GDB or + GDBserver. + + Copyright (C) 2019-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "gdbsupport/common-defs.h" +#include "gdbsupport/common-inferior.h" + +/* See common-inferior.h. */ + +bool startup_with_shell = true; diff --git a/gdbsupport/common-inferior.h b/gdbsupport/common-inferior.h new file mode 100644 index 0000000..3c8e87a --- /dev/null +++ b/gdbsupport/common-inferior.h @@ -0,0 +1,61 @@ +/* Functions to deal with the inferior being executed on GDB or + GDBserver. + + Copyright (C) 1986-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_COMMON_INFERIOR_H +#define COMMON_COMMON_INFERIOR_H + +/* Return the exec wrapper to be used when starting the inferior, or NULL + otherwise. */ +extern const char *get_exec_wrapper (); + +/* Return the name of the executable file as a string. + ERR nonzero means get error if there is none specified; + otherwise return 0 in that case. */ +extern const char *get_exec_file (int err); + +/* Return the inferior's current working directory. If nothing has + been set, then return NULL. */ +extern const char *get_inferior_cwd (); + +/* Set the inferior current working directory. If CWD is NULL, unset + the directory. */ +extern void set_inferior_cwd (const char *cwd); + +/* Whether to start up the debuggee under a shell. + + If startup-with-shell is set, GDB's "run" will attempt to start up + the debuggee under a shell. This also happens when using GDBserver + under extended remote mode. + + This is in order for argument-expansion to occur. E.g., + + (gdb) run * + + The "*" gets expanded by the shell into a list of files. + + While this is a nice feature, it may be handy to bypass the shell + in some cases. To disable this feature, do "set startup-with-shell + false". + + The catch-exec traps expected during start-up will be one more if + the target is started up with a shell. */ +extern bool startup_with_shell; + +#endif /* COMMON_COMMON_INFERIOR_H */ diff --git a/gdbsupport/common-regcache.c b/gdbsupport/common-regcache.c new file mode 100644 index 0000000..86b3a36 --- /dev/null +++ b/gdbsupport/common-regcache.c @@ -0,0 +1,36 @@ +/* Cache and manage the values of registers for GDB, the GNU debugger. + + Copyright (C) 2015-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "common-defs.h" +#include "common-regcache.h" + +/* Return the register's value or throw if it's not available. */ + +ULONGEST +regcache_raw_get_unsigned (struct regcache *regcache, int regnum) +{ + ULONGEST value; + enum register_status status; + + status = regcache_raw_read_unsigned (regcache, regnum, &value); + if (status == REG_UNAVAILABLE) + throw_error (NOT_AVAILABLE_ERROR, + _("Register %d is not available"), regnum); + return value; +} diff --git a/gdbsupport/common-regcache.h b/gdbsupport/common-regcache.h new file mode 100644 index 0000000..18446ff --- /dev/null +++ b/gdbsupport/common-regcache.h @@ -0,0 +1,85 @@ +/* Cache and manage the values of registers + + Copyright (C) 2014-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_COMMON_REGCACHE_H +#define COMMON_COMMON_REGCACHE_H + +/* This header is a stopgap until we have an independent regcache. */ + +enum register_status : signed char + { + /* The register value is not in the cache, and we don't know yet + whether it's available in the target (or traceframe). */ + REG_UNKNOWN = 0, + + /* The register value is valid and cached. */ + REG_VALID = 1, + + /* The register value is unavailable. E.g., we're inspecting a + traceframe, and this register wasn't collected. Note that this + is different a different "unavailable" from saying the register + does not exist in the target's architecture --- in that case, + the target should have given us a target description that does + not include the register in the first place. */ + REG_UNAVAILABLE = -1 + }; + +/* Return a pointer to the register cache associated with the + thread specified by PTID. This function must be provided by + the client. */ + +extern struct regcache *get_thread_regcache_for_ptid (ptid_t ptid); + +/* Return the size of register numbered N in REGCACHE. This function + must be provided by the client. */ + +extern int regcache_register_size (const struct regcache *regcache, int n); + +/* Read the PC register. This function must be provided by the + client. */ + +extern CORE_ADDR regcache_read_pc (struct regcache *regcache); + +/* Read a raw register into a unsigned integer. */ +extern enum register_status regcache_raw_read_unsigned + (struct regcache *regcache, int regnum, ULONGEST *val); + +ULONGEST regcache_raw_get_unsigned (struct regcache *regcache, int regnum); + +struct reg_buffer_common +{ + virtual ~reg_buffer_common () = default; + + /* Get the availability status of the value of register REGNUM in this + buffer. */ + virtual register_status get_register_status (int regnum) const = 0; + + /* Supply register REGNUM, whose contents are stored in BUF, to REGCACHE. */ + virtual void raw_supply (int regnum, const void *buf) = 0; + + /* Collect register REGNUM from REGCACHE and store its contents in BUF. */ + virtual void raw_collect (int regnum, void *buf) const = 0; + + /* Compare the contents of the register stored in the regcache (ignoring the + first OFFSET bytes) to the contents of BUF (without any offset). Returns + true if the same. */ + virtual bool raw_compare (int regnum, const void *buf, int offset) const = 0; +}; + +#endif /* COMMON_COMMON_REGCACHE_H */ diff --git a/gdbsupport/common-types.h b/gdbsupport/common-types.h new file mode 100644 index 0000000..61099b4 --- /dev/null +++ b/gdbsupport/common-types.h @@ -0,0 +1,66 @@ +/* Declarations for common types. + + Copyright (C) 1986-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_COMMON_TYPES_H +#define COMMON_COMMON_TYPES_H + +#ifdef GDBSERVER + +/* * A byte from the program being debugged. */ +typedef unsigned char gdb_byte; + +typedef unsigned long long CORE_ADDR; + +typedef long long LONGEST; +typedef unsigned long long ULONGEST; + +#else /* GDBSERVER */ + +#include "bfd.h" + +/* * A byte from the program being debugged. */ +typedef bfd_byte gdb_byte; + +/* * An address in the program being debugged. Host byte order. */ +typedef bfd_vma CORE_ADDR; + +/* This is to make sure that LONGEST is at least as big as CORE_ADDR. */ + +#ifdef BFD64 + +typedef BFD_HOST_64_BIT LONGEST; +typedef BFD_HOST_U_64_BIT ULONGEST; + +#else /* No BFD64 */ + +typedef long long LONGEST; +typedef unsigned long long ULONGEST; + +#endif /* No BFD64 */ +#endif /* GDBSERVER */ + +/* * The largest CORE_ADDR value. */ +#define CORE_ADDR_MAX (~(CORE_ADDR) 0) + +/* * The largest ULONGEST value. */ +#define ULONGEST_MAX (~(ULONGEST) 0) + +enum tribool { TRIBOOL_UNKNOWN = -1, TRIBOOL_FALSE = 0, TRIBOOL_TRUE = 1 }; + +#endif /* COMMON_COMMON_TYPES_H */ diff --git a/gdbsupport/common-utils.c b/gdbsupport/common-utils.c new file mode 100644 index 0000000..ed05d61 --- /dev/null +++ b/gdbsupport/common-utils.c @@ -0,0 +1,417 @@ +/* Shared general utility routines for GDB, the GNU debugger. + + Copyright (C) 1986-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "common-defs.h" +#include "common-utils.h" +#include "host-defs.h" +#include <ctype.h> + +void * +xzalloc (size_t size) +{ + return xcalloc (1, size); +} + +/* Like asprintf/vasprintf but get an internal_error if the call + fails. */ + +char * +xstrprintf (const char *format, ...) +{ + char *ret; + va_list args; + + va_start (args, format); + ret = xstrvprintf (format, args); + va_end (args); + return ret; +} + +char * +xstrvprintf (const char *format, va_list ap) +{ + char *ret = NULL; + int status = vasprintf (&ret, format, ap); + + /* NULL is returned when there was a memory allocation problem, or + any other error (for instance, a bad format string). A negative + status (the printed length) with a non-NULL buffer should never + happen, but just to be sure. */ + if (ret == NULL || status < 0) + internal_error (__FILE__, __LINE__, _("vasprintf call failed")); + return ret; +} + +int +xsnprintf (char *str, size_t size, const char *format, ...) +{ + va_list args; + int ret; + + va_start (args, format); + ret = vsnprintf (str, size, format, args); + gdb_assert (ret < size); + va_end (args); + + return ret; +} + +/* See documentation in common-utils.h. */ + +std::string +string_printf (const char* fmt, ...) +{ + va_list vp; + int size; + + va_start (vp, fmt); + size = vsnprintf (NULL, 0, fmt, vp); + va_end (vp); + + std::string str (size, '\0'); + + /* C++11 and later guarantee std::string uses contiguous memory and + always includes the terminating '\0'. */ + va_start (vp, fmt); + vsprintf (&str[0], fmt, vp); /* ARI: vsprintf */ + va_end (vp); + + return str; +} + +/* See documentation in common-utils.h. */ + +std::string +string_vprintf (const char* fmt, va_list args) +{ + va_list vp; + size_t size; + + va_copy (vp, args); + size = vsnprintf (NULL, 0, fmt, vp); + va_end (vp); + + std::string str (size, '\0'); + + /* C++11 and later guarantee std::string uses contiguous memory and + always includes the terminating '\0'. */ + vsprintf (&str[0], fmt, args); /* ARI: vsprintf */ + + return str; +} + + +/* See documentation in common-utils.h. */ + +void +string_appendf (std::string &str, const char *fmt, ...) +{ + va_list vp; + + va_start (vp, fmt); + string_vappendf (str, fmt, vp); + va_end (vp); +} + + +/* See documentation in common-utils.h. */ + +void +string_vappendf (std::string &str, const char *fmt, va_list args) +{ + va_list vp; + int grow_size; + + va_copy (vp, args); + grow_size = vsnprintf (NULL, 0, fmt, vp); + va_end (vp); + + size_t curr_size = str.size (); + str.resize (curr_size + grow_size); + + /* C++11 and later guarantee std::string uses contiguous memory and + always includes the terminating '\0'. */ + vsprintf (&str[curr_size], fmt, args); /* ARI: vsprintf */ +} + +char * +savestring (const char *ptr, size_t len) +{ + char *p = (char *) xmalloc (len + 1); + + memcpy (p, ptr, len); + p[len] = 0; + return p; +} + +/* See documentation in common-utils.h. */ + +std::string +extract_string_maybe_quoted (const char **arg) +{ + bool squote = false; + bool dquote = false; + bool bsquote = false; + std::string result; + const char *p = *arg; + + /* Find the start of the argument. */ + p = skip_spaces (p); + + /* Parse p similarly to gdb_argv buildargv function. */ + while (*p != '\0') + { + if (isspace (*p) && !squote && !dquote && !bsquote) + break; + else + { + if (bsquote) + { + bsquote = false; + result += *p; + } + else if (*p == '\\') + bsquote = true; + else if (squote) + { + if (*p == '\'') + squote = false; + else + result += *p; + } + else if (dquote) + { + if (*p == '"') + dquote = false; + else + result += *p; + } + else + { + if (*p == '\'') + squote = true; + else if (*p == '"') + dquote = true; + else + result += *p; + } + p++; + } + } + + *arg = p; + return result; +} + +/* The bit offset of the highest byte in a ULONGEST, for overflow + checking. */ + +#define HIGH_BYTE_POSN ((sizeof (ULONGEST) - 1) * HOST_CHAR_BIT) + +/* True (non-zero) iff DIGIT is a valid digit in radix BASE, + where 2 <= BASE <= 36. */ + +static int +is_digit_in_base (unsigned char digit, int base) +{ + if (!isalnum (digit)) + return 0; + if (base <= 10) + return (isdigit (digit) && digit < base + '0'); + else + return (isdigit (digit) || tolower (digit) < base - 10 + 'a'); +} + +static int +digit_to_int (unsigned char c) +{ + if (isdigit (c)) + return c - '0'; + else + return tolower (c) - 'a' + 10; +} + +/* As for strtoul, but for ULONGEST results. */ + +ULONGEST +strtoulst (const char *num, const char **trailer, int base) +{ + unsigned int high_part; + ULONGEST result; + int minus = 0; + int i = 0; + + /* Skip leading whitespace. */ + while (isspace (num[i])) + i++; + + /* Handle prefixes. */ + if (num[i] == '+') + i++; + else if (num[i] == '-') + { + minus = 1; + i++; + } + + if (base == 0 || base == 16) + { + if (num[i] == '0' && (num[i + 1] == 'x' || num[i + 1] == 'X')) + { + i += 2; + if (base == 0) + base = 16; + } + } + + if (base == 0 && num[i] == '0') + base = 8; + + if (base == 0) + base = 10; + + if (base < 2 || base > 36) + { + errno = EINVAL; + return 0; + } + + result = high_part = 0; + for (; is_digit_in_base (num[i], base); i += 1) + { + result = result * base + digit_to_int (num[i]); + high_part = high_part * base + (unsigned int) (result >> HIGH_BYTE_POSN); + result &= ((ULONGEST) 1 << HIGH_BYTE_POSN) - 1; + if (high_part > 0xff) + { + errno = ERANGE; + result = ~ (ULONGEST) 0; + high_part = 0; + minus = 0; + break; + } + } + + if (trailer != NULL) + *trailer = &num[i]; + + result = result + ((ULONGEST) high_part << HIGH_BYTE_POSN); + if (minus) + return -result; + else + return result; +} + +/* See documentation in common-utils.h. */ + +char * +skip_spaces (char *chp) +{ + if (chp == NULL) + return NULL; + while (*chp && isspace (*chp)) + chp++; + return chp; +} + +/* A const-correct version of the above. */ + +const char * +skip_spaces (const char *chp) +{ + if (chp == NULL) + return NULL; + while (*chp && isspace (*chp)) + chp++; + return chp; +} + +/* See documentation in common-utils.h. */ + +const char * +skip_to_space (const char *chp) +{ + if (chp == NULL) + return NULL; + while (*chp && !isspace (*chp)) + chp++; + return chp; +} + +/* See documentation in common-utils.h. */ + +char * +skip_to_space (char *chp) +{ + return (char *) skip_to_space ((const char *) chp); +} + +/* See gdbsupport/common-utils.h. */ + +void +free_vector_argv (std::vector<char *> &v) +{ + for (char *el : v) + xfree (el); + + v.clear (); +} + +/* See gdbsupport/common-utils.h. */ + +std::string +stringify_argv (const std::vector<char *> &args) +{ + std::string ret; + + if (!args.empty () && args[0] != NULL) + { + for (auto s : args) + if (s != NULL) + { + ret += s; + ret += ' '; + } + + /* Erase the last whitespace. */ + ret.erase (ret.end () - 1); + } + + return ret; +} + +/* See gdbsupport/common-utils.h. */ + +ULONGEST +align_up (ULONGEST v, int n) +{ + /* Check that N is really a power of two. */ + gdb_assert (n && (n & (n-1)) == 0); + return (v + n - 1) & -n; +} + +/* See gdbsupport/common-utils.h. */ + +ULONGEST +align_down (ULONGEST v, int n) +{ + /* Check that N is really a power of two. */ + gdb_assert (n && (n & (n-1)) == 0); + return (v & -n); +} diff --git a/gdbsupport/common-utils.h b/gdbsupport/common-utils.h new file mode 100644 index 0000000..ba03427 --- /dev/null +++ b/gdbsupport/common-utils.h @@ -0,0 +1,202 @@ +/* Shared general utility routines for GDB, the GNU debugger. + + Copyright (C) 1986-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_COMMON_UTILS_H +#define COMMON_COMMON_UTILS_H + +#include <string> +#include <vector> + +#include "poison.h" + +/* If possible, define FUNCTION_NAME, a macro containing the name of + the function being defined. Since this macro may not always be + defined, all uses must be protected by appropriate macro definition + checks (Eg: "#ifdef FUNCTION_NAME"). + + Version 2.4 and later of GCC define a magical variable `__PRETTY_FUNCTION__' + which contains the name of the function currently being defined. + This is broken in G++ before version 2.6. + C9x has a similar variable called __func__, but prefer the GCC one since + it demangles C++ function names. */ +#if (GCC_VERSION >= 2004) +#define FUNCTION_NAME __PRETTY_FUNCTION__ +#else +#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L +#define FUNCTION_NAME __func__ /* ARI: func */ +#endif +#endif + +#include "gdb_string_view.h" + +/* xmalloc(), xrealloc() and xcalloc() have already been declared in + "libiberty.h". */ + +/* Like xmalloc, but zero the memory. */ +void *xzalloc (size_t); + +template <typename T> +static void +xfree (T *ptr) +{ + static_assert (IsFreeable<T>::value, "Trying to use xfree with a non-POD \ +data type. Use operator delete instead."); + + if (ptr != NULL) + free (ptr); /* ARI: free */ +} + + +/* Like asprintf and vasprintf, but return the string, throw an error + if no memory. */ +char *xstrprintf (const char *format, ...) ATTRIBUTE_PRINTF (1, 2); +char *xstrvprintf (const char *format, va_list ap) + ATTRIBUTE_PRINTF (1, 0); + +/* Like snprintf, but throw an error if the output buffer is too small. */ +int xsnprintf (char *str, size_t size, const char *format, ...) + ATTRIBUTE_PRINTF (3, 4); + +/* Returns a std::string built from a printf-style format string. */ +std::string string_printf (const char* fmt, ...) + ATTRIBUTE_PRINTF (1, 2); + +/* Like string_printf, but takes a va_list. */ +std::string string_vprintf (const char* fmt, va_list args) + ATTRIBUTE_PRINTF (1, 0); + +/* Like string_printf, but appends to DEST instead of returning a new + std::string. */ +void string_appendf (std::string &dest, const char* fmt, ...) + ATTRIBUTE_PRINTF (2, 3); + +/* Like string_appendf, but takes a va_list. */ +void string_vappendf (std::string &dest, const char* fmt, va_list args) + ATTRIBUTE_PRINTF (2, 0); + +/* Make a copy of the string at PTR with LEN characters + (and add a null character at the end in the copy). + Uses malloc to get the space. Returns the address of the copy. */ + +char *savestring (const char *ptr, size_t len); + +/* Extract the next word from ARG. The next word is defined as either, + everything up to the next space, or, if the next word starts with either + a single or double quote, then everything up to the closing quote. The + enclosing quotes are not returned in the result string. The pointer in + ARG is updated to point to the first character after the end of the + word, or, for quoted words, the first character after the closing + quote. */ + +std::string extract_string_maybe_quoted (const char **arg); + +/* The strerror() function can return NULL for errno values that are + out of range. Provide a "safe" version that always returns a + printable string. This version is also thread-safe. */ + +extern const char *safe_strerror (int); + +/* Return true if the start of STRING matches PATTERN, false otherwise. */ + +static inline bool +startswith (const char *string, const char *pattern) +{ + return strncmp (string, pattern, strlen (pattern)) == 0; +} + +/* Version of startswith that takes string_view arguments. See comment + above. */ + +static inline bool +startswith (gdb::string_view string, gdb::string_view pattern) +{ + return (string.length () >= pattern.length () + && strncmp (string.data (), pattern.data (), pattern.length ()) == 0); +} + +ULONGEST strtoulst (const char *num, const char **trailer, int base); + +/* Skip leading whitespace characters in INP, returning an updated + pointer. If INP is NULL, return NULL. */ + +extern char *skip_spaces (char *inp); + +/* A const-correct version of the above. */ + +extern const char *skip_spaces (const char *inp); + +/* Skip leading non-whitespace characters in INP, returning an updated + pointer. If INP is NULL, return NULL. */ + +extern char *skip_to_space (char *inp); + +/* A const-correct version of the above. */ + +extern const char *skip_to_space (const char *inp); + +/* Assumes that V is an argv for a program, and iterates through + freeing all the elements. */ +extern void free_vector_argv (std::vector<char *> &v); + +/* Given a vector of arguments ARGV, return a string equivalent to + joining all the arguments with a whitespace separating them. */ +extern std::string stringify_argv (const std::vector<char *> &argv); + +/* Return true if VALUE is in [LOW, HIGH]. */ + +template <typename T> +static bool +in_inclusive_range (T value, T low, T high) +{ + return value >= low && value <= high; +} + +/* Ensure that V is aligned to an N byte boundary (B's assumed to be a + power of 2). Round up/down when necessary. Examples of correct + use include: + + addr = align_up (addr, 8); -- VALUE needs 8 byte alignment + write_memory (addr, value, len); + addr += len; + + and: + + sp = align_down (sp - len, 16); -- Keep SP 16 byte aligned + write_memory (sp, value, len); + + Note that uses such as: + + write_memory (addr, value, len); + addr += align_up (len, 8); + + and: + + sp -= align_up (len, 8); + write_memory (sp, value, len); + + are typically not correct as they don't ensure that the address (SP + or ADDR) is correctly aligned (relying on previous alignment to + keep things right). This is also why the methods are called + "align_..." instead of "round_..." as the latter reads better with + this incorrect coding style. */ + +extern ULONGEST align_up (ULONGEST v, int n); +extern ULONGEST align_down (ULONGEST v, int n); + +#endif /* COMMON_COMMON_UTILS_H */ diff --git a/gdbsupport/common.m4 b/gdbsupport/common.m4 new file mode 100644 index 0000000..9e15940 --- /dev/null +++ b/gdbsupport/common.m4 @@ -0,0 +1,93 @@ +dnl Autoconf configure snippets for common. +dnl Copyright (C) 1995-2020 Free Software Foundation, Inc. +dnl +dnl This file is part of GDB. +dnl +dnl This program is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 3 of the License, or +dnl (at your option) any later version. +dnl +dnl This program is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with this program. If not, see <http://www.gnu.org/licenses/>. + +dnl Invoke configury needed by the files in 'common'. +AC_DEFUN([GDB_AC_COMMON], [ + AC_HEADER_STDC + AC_FUNC_ALLOCA + + WIN32APILIBS= + case ${host} in + *mingw32*) + AC_DEFINE(USE_WIN32API, 1, + [Define if we should use the Windows API, instead of the + POSIX API. On Windows, we use the Windows API when + building for MinGW, but the POSIX API when building + for Cygwin.]) + WIN32APILIBS="-lws2_32" + ;; + esac + + dnl Note that this requires codeset.m4, which is included + dnl by the users of common.m4. + AM_LANGINFO_CODESET + + AC_CHECK_HEADERS(linux/perf_event.h locale.h memory.h signal.h dnl + sys/resource.h sys/socket.h dnl + sys/un.h sys/wait.h dnl + thread_db.h wait.h dnl + termios.h dnl + dlfcn.h) + + AC_CHECK_FUNCS([fdwalk getrlimit pipe pipe2 socketpair sigaction \ + sigprocmask]) + + AC_CHECK_DECLS([strstr]) + + # Check for std::thread. This does not work on some platforms, like + # mingw and DJGPP. + AC_LANG_PUSH([C++]) + AX_PTHREAD([threads=yes], [threads=no]) + if test "$threads" = "yes"; then + save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" + save_CXXFLAGS="$CXXFLAGS" + CXXFLAGS="$PTHREAD_CFLAGS $save_CXXFLAGS" + AC_CACHE_CHECK([for std::thread], + gdb_cv_cxx_std_thread, + [AC_COMPILE_IFELSE([AC_LANG_PROGRAM( + [[#include <thread> + void callback() { }]], + [[std::thread t(callback);]])], + gdb_cv_cxx_std_thread=yes, + gdb_cv_cxx_std_thread=no)]) + + # This check must be here, while LIBS includes any necessary + # threading library. + AC_CHECK_FUNCS([pthread_sigmask pthread_setname_np]) + + LIBS="$save_LIBS" + CXXFLAGS="$save_CXXFLAGS" + fi + if test "$gdb_cv_cxx_std_thread" = "yes"; then + AC_DEFINE(CXX_STD_THREAD, 1, + [Define to 1 if std::thread works.]) + fi + AC_LANG_POP + + dnl Check if sigsetjmp is available. Using AC_CHECK_FUNCS won't + dnl do since sigsetjmp might only be defined as a macro. + AC_CACHE_CHECK([for sigsetjmp], gdb_cv_func_sigsetjmp, + [AC_TRY_COMPILE([ + #include <setjmp.h> + ], [sigjmp_buf env; while (! sigsetjmp (env, 1)) siglongjmp (env, 1);], + gdb_cv_func_sigsetjmp=yes, gdb_cv_func_sigsetjmp=no)]) + if test "$gdb_cv_func_sigsetjmp" = "yes"; then + AC_DEFINE(HAVE_SIGSETJMP, 1, [Define if sigsetjmp is available. ]) + fi +]) diff --git a/gdbsupport/config.in b/gdbsupport/config.in new file mode 100644 index 0000000..4a8508b --- /dev/null +++ b/gdbsupport/config.in @@ -0,0 +1,274 @@ +/* config.in. Generated from configure.ac by autoheader. */ + +/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP + systems. This function is required for `alloca.c' support on those systems. + */ +#undef CRAY_STACKSEG_END + +/* Define to 1 if std::thread works. */ +#undef CXX_STD_THREAD + +/* Define to 1 if using `alloca.c'. */ +#undef C_ALLOCA + +/* Define to 1 if translation of program messages to the user's native + language is requested. */ +#undef ENABLE_NLS + +/* Define if self-testing features should be enabled */ +#undef GDB_SELF_TEST + +/* Define to 1 if you have `alloca', as a function or macro. */ +#undef HAVE_ALLOCA + +/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix). + */ +#undef HAVE_ALLOCA_H + +/* define if the compiler supports basic C++11 syntax */ +#undef HAVE_CXX11 + +/* Define to 1 if you have the declaration of `asprintf', and to 0 if you + don't. */ +#undef HAVE_DECL_ASPRINTF + +/* Define to 1 if you have the declaration of `basename(char *)', and to 0 if + you don't. */ +#undef HAVE_DECL_BASENAME + +/* Define to 1 if you have the declaration of `ffs', and to 0 if you don't. */ +#undef HAVE_DECL_FFS + +/* Define to 1 if you have the declaration of `snprintf', and to 0 if you + don't. */ +#undef HAVE_DECL_SNPRINTF + +/* Define to 1 if you have the declaration of `strstr', and to 0 if you don't. + */ +#undef HAVE_DECL_STRSTR + +/* Define to 1 if you have the declaration of `strtol', and to 0 if you don't. + */ +#undef HAVE_DECL_STRTOL + +/* Define to 1 if you have the declaration of `strtoll', and to 0 if you + don't. */ +#undef HAVE_DECL_STRTOLL + +/* Define to 1 if you have the declaration of `strtoul', and to 0 if you + don't. */ +#undef HAVE_DECL_STRTOUL + +/* Define to 1 if you have the declaration of `strtoull', and to 0 if you + don't. */ +#undef HAVE_DECL_STRTOULL + +/* Define to 1 if you have the declaration of `strverscmp', and to 0 if you + don't. */ +#undef HAVE_DECL_STRVERSCMP + +/* Define to 1 if you have the declaration of `vasprintf', and to 0 if you + don't. */ +#undef HAVE_DECL_VASPRINTF + +/* Define to 1 if you have the declaration of `vsnprintf', and to 0 if you + don't. */ +#undef HAVE_DECL_VSNPRINTF + +/* Define to 1 if you have the <dlfcn.h> header file. */ +#undef HAVE_DLFCN_H + +/* Define to 1 if you have the `fdwalk' function. */ +#undef HAVE_FDWALK + +/* Define to 1 if you have the `getrlimit' function. */ +#undef HAVE_GETRLIMIT + +/* Define to 1 if you have the <inttypes.h> header file. */ +#undef HAVE_INTTYPES_H + +/* Define if you have <langinfo.h> and nl_langinfo(CODESET). */ +#undef HAVE_LANGINFO_CODESET + +/* Define to 1 if you have the <linux/perf_event.h> header file. */ +#undef HAVE_LINUX_PERF_EVENT_H + +/* Define to 1 if you have the <locale.h> header file. */ +#undef HAVE_LOCALE_H + +/* Define to 1 if the system has the type `long long'. */ +#undef HAVE_LONG_LONG + +/* Define to 1 if you have the <memory.h> header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the `pipe' function. */ +#undef HAVE_PIPE + +/* Define to 1 if you have the `pipe2' function. */ +#undef HAVE_PIPE2 + +/* Have PTHREAD_PRIO_INHERIT. */ +#undef HAVE_PTHREAD_PRIO_INHERIT + +/* Define to 1 if you have the `pthread_setname_np' function. */ +#undef HAVE_PTHREAD_SETNAME_NP + +/* Define to 1 if you have the `pthread_sigmask' function. */ +#undef HAVE_PTHREAD_SIGMASK + +/* Define to 1 if you have the `sigaction' function. */ +#undef HAVE_SIGACTION + +/* Define to 1 if you have the <signal.h> header file. */ +#undef HAVE_SIGNAL_H + +/* Define to 1 if you have the `sigprocmask' function. */ +#undef HAVE_SIGPROCMASK + +/* Define if sigsetjmp is available. */ +#undef HAVE_SIGSETJMP + +/* Define to 1 if you have the `socketpair' function. */ +#undef HAVE_SOCKETPAIR + +/* Define to 1 if you have the <stdint.h> header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the <stdlib.h> header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the <strings.h> header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the <string.h> header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the <sys/resource.h> header file. */ +#undef HAVE_SYS_RESOURCE_H + +/* Define to 1 if you have the <sys/socket.h> header file. */ +#undef HAVE_SYS_SOCKET_H + +/* Define to 1 if you have the <sys/stat.h> header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the <sys/types.h> header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the <sys/un.h> header file. */ +#undef HAVE_SYS_UN_H + +/* Define to 1 if you have the <sys/wait.h> header file. */ +#undef HAVE_SYS_WAIT_H + +/* Define to 1 if you have the <termios.h> header file. */ +#undef HAVE_TERMIOS_H + +/* Define to 1 if you have the <thread_db.h> header file. */ +#undef HAVE_THREAD_DB_H + +/* Define to 1 if you have the <unistd.h> header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if you have the <wait.h> header file. */ +#undef HAVE_WAIT_H + +/* Define to 1 if you have the <windows.h> header file. */ +#undef HAVE_WINDOWS_H + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define to necessary symbol if this constant uses a non-standard name on + your system. */ +#undef PTHREAD_CREATE_JOINABLE + +/* The size of `long long', as computed by sizeof. */ +#undef SIZEOF_LONG_LONG + +/* 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 runtime. + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown */ +#undef STACK_DIRECTION + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define to the word size for the target. */ +#undef TARGET_WORD_SIZE + +/* Enable extensions on AIX 3, Interix. */ +#ifndef _ALL_SOURCE +# undef _ALL_SOURCE +#endif +/* Enable GNU extensions on systems that have them. */ +#ifndef _GNU_SOURCE +# undef _GNU_SOURCE +#endif +/* Enable threading extensions on Solaris. */ +#ifndef _POSIX_PTHREAD_SEMANTICS +# undef _POSIX_PTHREAD_SEMANTICS +#endif +/* Enable extensions on HP NonStop. */ +#ifndef _TANDEM_SOURCE +# undef _TANDEM_SOURCE +#endif +/* Enable general extensions on Solaris. */ +#ifndef __EXTENSIONS__ +# undef __EXTENSIONS__ +#endif + + +/* Define if we should use the Windows API, instead of the POSIX API. On + Windows, we use the Windows API when building for MinGW, but the POSIX API + when building for Cygwin. */ +#undef USE_WIN32API + +/* Version number of package */ +#undef VERSION + +/* Enable large inode numbers on Mac OS X 10.5. */ +#ifndef _DARWIN_USE_64_BIT_INODE +# define _DARWIN_USE_64_BIT_INODE 1 +#endif + +/* Number of bits in a file offset, on hosts where this is settable. */ +#undef _FILE_OFFSET_BITS + +/* Define for large files, on AIX-style hosts. */ +#undef _LARGE_FILES + +/* Define to 1 if on MINIX. */ +#undef _MINIX + +/* Define to 2 if the system does not provide POSIX.1 features except with + this defined. */ +#undef _POSIX_1_SOURCE + +/* Define to 1 if you need to in order for `stat' and other things to work. */ +#undef _POSIX_SOURCE + +/* Define to `unsigned int' if <sys/types.h> does not define. */ +#undef size_t diff --git a/gdbsupport/configure b/gdbsupport/configure new file mode 100755 index 0000000..2f44d03 --- /dev/null +++ b/gdbsupport/configure @@ -0,0 +1,10425 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.69 for gdbsupport 1.0. +# +# +# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# Use a proper internal environment variable to ensure we don't fall + # into an infinite loop, continuously re-executing ourselves. + if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then + _as_can_reexec=no; export _as_can_reexec; + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +as_fn_exit 255 + fi + # We don't want this to propagate to other subprocesses. + { _as_can_reexec=; unset _as_can_reexec;} +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1 +test -x / || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + export CONFIG_SHELL + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." + else + $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, +$0: including any error possibly output before this +$0: message. Then install a modern shell, or manually run +$0: the script under such a shell if you do have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # If we had to re-execute with $CONFIG_SHELL, we're ensured to have + # already done that, so ensure we don't try to do so again and fall + # in an infinite loop. This has already happened in practice. + _as_can_reexec=no; export _as_can_reexec + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +test -n "$DJDIR" || exec 7<&0 </dev/null +exec 6>&1 + +# Name of the host. +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME='gdbsupport' +PACKAGE_TARNAME='gdbsupport' +PACKAGE_VERSION='1.0' +PACKAGE_STRING='gdbsupport 1.0' +PACKAGE_BUGREPORT='' +PACKAGE_URL='' + +ac_unique_file="common-defs.h" +# Factoring default headers for most tests. +ac_includes_default="\ +#include <stdio.h> +#ifdef HAVE_SYS_TYPES_H +# include <sys/types.h> +#endif +#ifdef HAVE_SYS_STAT_H +# include <sys/stat.h> +#endif +#ifdef STDC_HEADERS +# include <stdlib.h> +# include <stddef.h> +#else +# ifdef HAVE_STDLIB_H +# include <stdlib.h> +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include <memory.h> +# endif +# include <string.h> +#endif +#ifdef HAVE_STRINGS_H +# include <strings.h> +#endif +#ifdef HAVE_INTTYPES_H +# include <inttypes.h> +#endif +#ifdef HAVE_STDINT_H +# include <stdint.h> +#endif +#ifdef HAVE_UNISTD_H +# include <unistd.h> +#endif" + +ac_subst_vars='am__EXEEXT_FALSE +am__EXEEXT_TRUE +LTLIBOBJS +LIBOBJS +SELFTEST_FALSE +SELFTEST_TRUE +PTHREAD_CFLAGS +PTHREAD_LIBS +PTHREAD_CC +ax_pthread_config +SED +ALLOCA +CATOBJEXT +GENCAT +INSTOBJEXT +DATADIRNAME +CATALOGS +POSUB +GMSGFMT +XGETTEXT +INCINTL +LIBINTL_DEP +LIBINTL +USE_NLS +CXX_DIALECT +HAVE_CXX11 +EGREP +GREP +CPP +RANLIB +am__fastdepCXX_FALSE +am__fastdepCXX_TRUE +CXXDEPMODE +ac_ct_CXX +CXXFLAGS +CXX +am__fastdepCC_FALSE +am__fastdepCC_TRUE +CCDEPMODE +am__nodep +AMDEPBACKSLASH +AMDEP_FALSE +AMDEP_TRUE +am__quote +am__include +DEPDIR +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +CC +AM_BACKSLASH +AM_DEFAULT_VERBOSITY +AM_DEFAULT_V +AM_V +am__untar +am__tar +AMTAR +am__leading_dot +SET_MAKE +AWK +mkdir_p +MKDIR_P +INSTALL_STRIP_PROGRAM +STRIP +install_sh +MAKEINFO +AUTOHEADER +AUTOMAKE +AUTOCONF +ACLOCAL +VERSION +PACKAGE +CYGPATH_W +am__isrc +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +MAINT +MAINTAINER_MODE_FALSE +MAINTAINER_MODE_TRUE +target_os +target_vendor +target_cpu +target +host_os +host_vendor +host_cpu +host +build_os +build_vendor +build_cpu +build +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +enable_maintainer_mode +enable_silent_rules +enable_dependency_tracking +enable_plugins +enable_largefile +enable_unit_tests +' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CXX +CXXFLAGS +CCC +CPP' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error $? "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures gdbsupport 1.0 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking ...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/gdbsupport] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] + --target=TARGET configure for building compilers for TARGET [HOST] +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of gdbsupport 1.0:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-maintainer-mode + enable make rules and dependencies not useful (and + sometimes confusing) to the casual installer + --enable-silent-rules less verbose build output (undo: "make V=1") + --disable-silent-rules verbose build output (undo: "make V=0") + --enable-dependency-tracking + do not reject slow dependency extractors + --disable-dependency-tracking + speeds up one-time build + --enable-plugins Enable support for plugins + --disable-largefile omit support for large files + --enable-unit-tests Enable the inclusion of unit tests when compiling + GDB + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a + nonstandard directory <lib dir> + LIBS libraries to pass to the linker, e.g. -l<library> + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if + you have headers in a nonstandard directory <include dir> + CXX C++ compiler command + CXXFLAGS C++ compiler flags + CPP C preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to the package provider. +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +gdbsupport configure 1.0 +generated by GNU Autoconf 2.69 + +Copyright (C) 2012 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_compile + +# ac_fn_cxx_try_compile LINENO +# ---------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_compile + +# ac_fn_c_try_cpp LINENO +# ---------------------- +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_cpp + +# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists, giving a warning if it cannot be compiled using +# the include files in INCLUDES and setting the cache variable VAR +# accordingly. +ac_fn_c_check_header_mongrel () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if eval \${$3+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 +$as_echo_n "checking $2 usability... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_header_compiler=yes +else + ac_header_compiler=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 +$as_echo_n "checking $2 presence... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <$2> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + ac_header_preproc=yes +else + ac_header_preproc=no +fi +rm -f conftest.err conftest.i conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( + yes:no: ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; + no:yes:* ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; +esac + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=\$ac_header_compiler" +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_mongrel + +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +# that executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then : + ac_retval=0 +else + $as_echo "$as_me: program exited with status $ac_status" >&5 + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_run + +# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_c_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_compile + +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + test -x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_link + +# ac_fn_c_check_type LINENO TYPE VAR INCLUDES +# ------------------------------------------- +# Tests whether TYPE exists after having included INCLUDES, setting cache +# variable VAR accordingly. +ac_fn_c_check_type () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=no" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof ($2)) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof (($2))) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + eval "$3=yes" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_type + +# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES +# -------------------------------------------- +# Tries to find the compile-time value of EXPR in a program that includes +# INCLUDES, setting VAR accordingly. Returns whether the value could be +# computed +ac_fn_c_compute_int () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if test "$cross_compiling" = yes; then + # Depending upon the size, compute the lo and hi bounds. +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) >= 0)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_lo=0 ac_mid=0 + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) <= $ac_mid)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_hi=$ac_mid; break +else + as_fn_arith $ac_mid + 1 && ac_lo=$as_val + if test $ac_lo -le $ac_mid; then + ac_lo= ac_hi= + break + fi + as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) < 0)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_hi=-1 ac_mid=-1 + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) >= $ac_mid)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_lo=$ac_mid; break +else + as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val + if test $ac_mid -le $ac_hi; then + ac_lo= ac_hi= + break + fi + as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + ac_lo= ac_hi= +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +# Binary search between lo and hi bounds. +while test "x$ac_lo" != "x$ac_hi"; do + as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) <= $ac_mid)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_hi=$ac_mid +else + as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +done +case $ac_lo in #(( +?*) eval "$3=\$ac_lo"; ac_retval=0 ;; +'') ac_retval=1 ;; +esac + else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +static long int longval () { return $2; } +static unsigned long int ulongval () { return $2; } +#include <stdio.h> +#include <stdlib.h> +int +main () +{ + + FILE *f = fopen ("conftest.val", "w"); + if (! f) + return 1; + if (($2) < 0) + { + long int i = longval (); + if (i != ($2)) + return 1; + fprintf (f, "%ld", i); + } + else + { + unsigned long int i = ulongval (); + if (i != ($2)) + return 1; + fprintf (f, "%lu", i); + } + /* Do not output a trailing newline, as this causes \r\n confusion + on some platforms. */ + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + echo >>conftest.val; read $3 <conftest.val; ac_retval=0 +else + ac_retval=1 +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +rm -f conftest.val + + fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_compute_int + +# ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES +# --------------------------------------------- +# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR +# accordingly. +ac_fn_c_check_decl () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + as_decl_name=`echo $2|sed 's/ *(.*//'` + as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5 +$as_echo_n "checking whether $as_decl_name is declared... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +#ifndef $as_decl_name +#ifdef __cplusplus + (void) $as_decl_use; +#else + (void) $as_decl_name; +#endif +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_decl + +# ac_fn_c_check_func LINENO FUNC VAR +# ---------------------------------- +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_c_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case <limits.h> declares $2. + For example, HP-UX 11i <limits.h> declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + <limits.h> exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $2 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$2 || defined __stub___$2 +choke me +#endif + +int +main () +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_func + +# ac_fn_cxx_try_link LINENO +# ------------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + test -x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_link + +# ac_fn_cxx_check_func LINENO FUNC VAR +# ------------------------------------ +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_cxx_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case <limits.h> declares $2. + For example, HP-UX 11i <limits.h> declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + <limits.h> exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $2 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$2 || defined __stub___$2 +choke me +#endif + +int +main () +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_cxx_check_func +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by gdbsupport $as_me 1.0, which was +generated by GNU Autoconf 2.69. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + $as_echo "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + $as_echo "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + $as_echo "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + $as_echo "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + # We do not want a PATH search for config.site. + case $CONFIG_SITE in #(( + -*) ac_site_file1=./$CONFIG_SITE;; + */*) ac_site_file1=$CONFIG_SITE;; + *) ac_site_file1=./$CONFIG_SITE;; + esac +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" \ + || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5; } + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + + + +ac_config_headers="$ac_config_headers support-config.h:config.in" + +ac_aux_dir= +for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +$as_echo_n "checking build system type... " >&6; } +if ${ac_cv_build+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +$as_echo "$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +$as_echo_n "checking host system type... " >&6; } +if ${ac_cv_host+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +$as_echo "$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking target system type" >&5 +$as_echo_n "checking target system type... " >&6; } +if ${ac_cv_target+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$target_alias" = x; then + ac_cv_target=$ac_cv_host +else + ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $target_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_target" >&5 +$as_echo "$ac_cv_target" >&6; } +case $ac_cv_target in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical target" "$LINENO" 5;; +esac +target=$ac_cv_target +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_target +shift +target_cpu=$1 +target_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +target_os=$* +IFS=$ac_save_IFS +case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac + + +# The aliases save the names the user supplied, while $host etc. +# will get canonicalized. +test -n "$target_alias" && + test "$program_prefix$program_suffix$program_transform_name" = \ + NONENONEs,x,x, && + program_prefix=${target_alias}- + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 +$as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; } + # Check whether --enable-maintainer-mode was given. +if test "${enable_maintainer_mode+set}" = set; then : + enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval +else + USE_MAINTAINER_MODE=no +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5 +$as_echo "$USE_MAINTAINER_MODE" >&6; } + if test $USE_MAINTAINER_MODE = yes; then + MAINTAINER_MODE_TRUE= + MAINTAINER_MODE_FALSE='#' +else + MAINTAINER_MODE_TRUE='#' + MAINTAINER_MODE_FALSE= +fi + + MAINT=$MAINTAINER_MODE_TRUE + + +ac_aux_dir= +for ac_dir in .. "$srcdir"/..; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + as_fn_error $? "cannot find install-sh, install.sh, or shtool in .. \"$srcdir\"/.." "$LINENO" 5 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +am__api_version='1.15' + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +$as_echo_n "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if ${ac_cv_path_install+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in #(( + ./ | .// | /[cC]/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + + done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +$as_echo "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 +$as_echo_n "checking whether build environment is sane... " >&6; } +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[\\\"\#\$\&\'\`$am_lf]*) + as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; +esac +case $srcdir in + *[\\\"\#\$\&\'\`$am_lf\ \ ]*) + as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; +esac + +# Do 'set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + as_fn_error $? "ls -t appears to fail. Make sure there is not a broken + alias in your environment" "$LINENO" 5 + fi + if test "$2" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done + test "$2" = conftest.file + ) +then + # Ok. + : +else + as_fn_error $? "newly created file is older than distributed files! +Check your system clock" "$LINENO" 5 +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi + +rm -f conftest.file + +test "$program_prefix" != NONE && + program_transform_name="s&^&$program_prefix&;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s&\$&$program_suffix&;$program_transform_name" +# Double any \ or $. +# By default was `s,x,x', remove it if useless. +ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' +program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` + +# Expand $ac_aux_dir to an absolute path. +am_aux_dir=`cd "$ac_aux_dir" && pwd` + +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " +else + am_missing_run= + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 +$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} +fi + +if test x"${install_sh+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi + +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the 'STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 +$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } +if test -z "$MKDIR_P"; then + if ${ac_cv_path_mkdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in mkdir gmkdir; do + for ac_exec_ext in '' $ac_executable_extensions; do + as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue + case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( + 'mkdir (GNU coreutils) '* | \ + 'mkdir (coreutils) '* | \ + 'mkdir (fileutils) '4.1*) + ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext + break 3;; + esac + done + done + done +IFS=$as_save_IFS + +fi + + test -d ./--version && rmdir ./--version + if test "${ac_cv_path_mkdir+set}" = set; then + MKDIR_P="$ac_cv_path_mkdir -p" + else + # As a last resort, use the slow shell script. Don't cache a + # value for MKDIR_P within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + MKDIR_P="$ac_install_sh -d" + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 +$as_echo "$MKDIR_P" >&6; } + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AWK+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AWK="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +$as_echo "$AWK" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AWK" && break +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +# Check whether --enable-silent-rules was given. +if test "${enable_silent_rules+set}" = set; then : + enableval=$enable_silent_rules; +fi + +case $enable_silent_rules in # ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=1;; +esac +am_make=${MAKE-make} +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 +$as_echo_n "checking whether $am_make supports nested variables... " >&6; } +if ${am_cv_make_support_nested_variables+:} false; then : + $as_echo_n "(cached) " >&6 +else + if $as_echo 'TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 +$as_echo "$am_cv_make_support_nested_variables" >&6; } +if test $am_cv_make_support_nested_variables = yes; then + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AM_BACKSLASH='\' + +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + am__isrc=' -I$(srcdir)' + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE='gdbsupport' + VERSION='1.0' + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE "$PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define VERSION "$VERSION" +_ACEOF + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html> +# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html> +mkdir_p='$(MKDIR_P)' + +# We need awk for the "check" target (and possibly the TAP driver). The +# system "awk" is bad on some platforms. +# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AMTAR='$${TAR-tar}' + + +# We'll loop over all known methods to create a tar archive until one works. +_am_tools='gnutar pax cpio none' + +am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' + + + + + + +# POSIX will say in a future version that running "rm -f" with no argument +# is OK; and we want to be able to make that assumption in our Makefile +# recipes. So use an aggressive probe to check that the usage we want is +# actually supported "in the wild" to an acceptable degree. +# See automake bug#10828. +# To make any issue more visible, cause the running configure to be aborted +# by default if the 'rm' program in use doesn't match our expectations; the +# user can still override this though. +if rm -f && rm -fr && rm -rf; then : OK; else + cat >&2 <<'END' +Oops! + +Your 'rm' program seems unable to run without file operands specified +on the command line, even when the '-f' option is present. This is contrary +to the behaviour of most rm programs out there, and not conforming with +the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542> + +Please tell bug-automake@gnu.org about your system, including the value +of your $PATH and any error possibly output before this message. This +can help us improve future automake versions. + +END + if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then + echo 'Configuration will proceed anyway, since you have set the' >&2 + echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 + echo >&2 + else + cat >&2 <<'END' +Aborting the configuration process, to ensure you take notice of the issue. + +You can download and install GNU coreutils to get an 'rm' implementation +that behaves properly: <http://www.gnu.org/software/coreutils/>. + +If you want to complete the configuration process using your problematic +'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +to "yes", and re-run configure. + +END + as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 + fi +fi + +# Check whether --enable-silent-rules was given. +if test "${enable_silent_rules+set}" = set; then : + enableval=$enable_silent_rules; +fi + +case $enable_silent_rules in # ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=0;; +esac +am_make=${MAKE-make} +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 +$as_echo_n "checking whether $am_make supports nested variables... " >&6; } +if ${am_cv_make_support_nested_variables+:} false; then : + $as_echo_n "(cached) " >&6 +else + if $as_echo 'TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 +$as_echo "$am_cv_make_support_nested_variables" >&6; } +if test $am_cv_make_support_nested_variables = yes; then + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AM_BACKSLASH='\' + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +$as_echo_n "checking whether the C compiler works... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi +if test -z "$ac_file"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "C compiler cannot create executables +See \`config.log' for more details" "$LINENO" 5; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +$as_echo_n "checking for C compiler default output file name... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +ac_exeext=$ac_cv_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest conftest$ac_cv_exeext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdio.h> +int +main () +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details" "$LINENO" 5; } + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if ${ac_cv_objext+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of object files: cannot compile +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdarg.h> +#include <stdio.h> +struct stat; +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 +$as_echo_n "checking whether $CC understands -c and -o together... " >&6; } +if ${am_cv_prog_cc_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 + ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 +$as_echo "$am_cv_prog_cc_c_o" >&6; } +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +DEPDIR="${am__leading_dot}deps" + +ac_config_commands="$ac_config_commands depfiles" + + +am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 +$as_echo_n "checking for style of include used by $am_make... " >&6; } +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from 'make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 +$as_echo "$_am_result" >&6; } +rm -f confinc confmf + +# Check whether --enable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then : + enableval=$enable_dependency_tracking; +fi + +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi + if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + + +depcc="$CC" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CC_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +if test -z "$CXX"; then + if test -n "$CCC"; then + CXX=$CCC + else + if test -n "$ac_tool_prefix"; then + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CXX"; then + ac_cv_prog_CXX="$CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CXX=$ac_cv_prog_CXX +if test -n "$CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 +$as_echo "$CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CXX" && break + done +fi +if test -z "$CXX"; then + ac_ct_CXX=$CXX + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CXX"; then + ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CXX="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CXX=$ac_cv_prog_ac_ct_CXX +if test -n "$ac_ct_CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 +$as_echo "$ac_ct_CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CXX" && break +done + + if test "x$ac_ct_CXX" = x; then + CXX="g++" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CXX=$ac_ct_CXX + fi +fi + + fi +fi +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 +$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } +if ${ac_cv_cxx_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_cxx_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 +$as_echo "$ac_cv_cxx_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GXX=yes +else + GXX= +fi +ac_test_CXXFLAGS=${CXXFLAGS+set} +ac_save_CXXFLAGS=$CXXFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 +$as_echo_n "checking whether $CXX accepts -g... " >&6; } +if ${ac_cv_prog_cxx_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_cxx_werror_flag=$ac_cxx_werror_flag + ac_cxx_werror_flag=yes + ac_cv_prog_cxx_g=no + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +else + CXXFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +else + ac_cxx_werror_flag=$ac_save_cxx_werror_flag + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cxx_werror_flag=$ac_save_cxx_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 +$as_echo "$ac_cv_prog_cxx_g" >&6; } +if test "$ac_test_CXXFLAGS" = set; then + CXXFLAGS=$ac_save_CXXFLAGS +elif test $ac_cv_prog_cxx_g = yes; then + if test "$GXX" = yes; then + CXXFLAGS="-g -O2" + else + CXXFLAGS="-g" + fi +else + if test "$GXX" = yes; then + CXXFLAGS="-O2" + else + CXXFLAGS= + fi +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +depcc="$CXX" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CXX_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CXX_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CXX_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CXX_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; } +CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then + am__fastdepCXX_TRUE= + am__fastdepCXX_FALSE='#' +else + am__fastdepCXX_TRUE='#' + am__fastdepCXX_FALSE= +fi + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if ${ac_cv_prog_CPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + # <limits.h> exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <ac_nonexistent.h> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +$as_echo "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + # <limits.h> exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <ac_nonexistent.h> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if ${ac_cv_path_GREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_GREP" || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if ${ac_cv_path_EGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_EGREP" || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <float.h> + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <string.h> + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdlib.h> + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <ctype.h> +#include <stdlib.h> +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + + ac_fn_c_check_header_mongrel "$LINENO" "minix/config.h" "ac_cv_header_minix_config_h" "$ac_includes_default" +if test "x$ac_cv_header_minix_config_h" = xyes; then : + MINIX=yes +else + MINIX= +fi + + + if test "$MINIX" = yes; then + +$as_echo "#define _POSIX_SOURCE 1" >>confdefs.h + + +$as_echo "#define _POSIX_1_SOURCE 2" >>confdefs.h + + +$as_echo "#define _MINIX 1" >>confdefs.h + + fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether it is safe to define __EXTENSIONS__" >&5 +$as_echo_n "checking whether it is safe to define __EXTENSIONS__... " >&6; } +if ${ac_cv_safe_to_define___extensions__+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +# define __EXTENSIONS__ 1 + $ac_includes_default +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_safe_to_define___extensions__=yes +else + ac_cv_safe_to_define___extensions__=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_safe_to_define___extensions__" >&5 +$as_echo "$ac_cv_safe_to_define___extensions__" >&6; } + test $ac_cv_safe_to_define___extensions__ = yes && + $as_echo "#define __EXTENSIONS__ 1" >>confdefs.h + + $as_echo "#define _ALL_SOURCE 1" >>confdefs.h + + $as_echo "#define _GNU_SOURCE 1" >>confdefs.h + + $as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h + + $as_echo "#define _TANDEM_SOURCE 1" >>confdefs.h + + + +# The tests for host and target for $enable_largefile require +# canonical names. + + + +# As the $enable_largefile decision depends on --enable-plugins we must set it +# even in directories otherwise not depending on the $plugins option. + + + maybe_plugins=no + for ac_header in dlfcn.h +do : + ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default +" +if test "x$ac_cv_header_dlfcn_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_DLFCN_H 1 +_ACEOF + maybe_plugins=yes +fi + +done + + for ac_header in windows.h +do : + ac_fn_c_check_header_compile "$LINENO" "windows.h" "ac_cv_header_windows_h" "$ac_includes_default +" +if test "x$ac_cv_header_windows_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_WINDOWS_H 1 +_ACEOF + maybe_plugins=yes +fi + +done + + + # Check whether --enable-plugins was given. +if test "${enable_plugins+set}" = set; then : + enableval=$enable_plugins; case "${enableval}" in + no) plugins=no ;; + *) plugins=yes + if test "$maybe_plugins" != "yes" ; then + as_fn_error $? "Building with plugin support requires a host that supports dlopen." "$LINENO" 5 + fi ;; + esac +else + plugins=$maybe_plugins + +fi + + if test "$plugins" = "yes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing dlsym" >&5 +$as_echo_n "checking for library containing dlsym... " >&6; } +if ${ac_cv_search_dlsym+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlsym (); +int +main () +{ +return dlsym (); + ; + return 0; +} +_ACEOF +for ac_lib in '' dl; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_dlsym=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_dlsym+:} false; then : + break +fi +done +if ${ac_cv_search_dlsym+:} false; then : + +else + ac_cv_search_dlsym=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_dlsym" >&5 +$as_echo "$ac_cv_search_dlsym" >&6; } +ac_res=$ac_cv_search_dlsym +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + + fi + + +case "${host}" in + sparc-*-solaris*|i[3-7]86-*-solaris*) + # On native 32bit sparc and ia32 solaris, large-file and procfs support + # are mutually exclusive; and without procfs support, the bfd/ elf module + # cannot provide certain routines such as elfcore_write_prpsinfo + # or elfcore_write_prstatus. So unless the user explicitly requested + # large-file support through the --enable-largefile switch, disable + # large-file support in favor of procfs support. + test "${target}" = "${host}" -a "x$plugins" = xno \ + && : ${enable_largefile="no"} + ;; +esac + +# Check whether --enable-largefile was given. +if test "${enable_largefile+set}" = set; then : + enableval=$enable_largefile; +fi + +if test "$enable_largefile" != no; then + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for special C compiler options needed for large files" >&5 +$as_echo_n "checking for special C compiler options needed for large files... " >&6; } +if ${ac_cv_sys_largefile_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_sys_largefile_CC=no + if test "$GCC" != yes; then + ac_save_CC=$CC + while :; do + # IRIX 6.2 and later do not support large files by default, + # so use the C compiler's -n32 option if that helps. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/types.h> + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF + if ac_fn_c_try_compile "$LINENO"; then : + break +fi +rm -f core conftest.err conftest.$ac_objext + CC="$CC -n32" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_largefile_CC=' -n32'; break +fi +rm -f core conftest.err conftest.$ac_objext + break + done + CC=$ac_save_CC + rm -f conftest.$ac_ext + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_CC" >&5 +$as_echo "$ac_cv_sys_largefile_CC" >&6; } + if test "$ac_cv_sys_largefile_CC" != no; then + CC=$CC$ac_cv_sys_largefile_CC + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _FILE_OFFSET_BITS value needed for large files" >&5 +$as_echo_n "checking for _FILE_OFFSET_BITS value needed for large files... " >&6; } +if ${ac_cv_sys_file_offset_bits+:} false; then : + $as_echo_n "(cached) " >&6 +else + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/types.h> + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_file_offset_bits=no; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#define _FILE_OFFSET_BITS 64 +#include <sys/types.h> + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_file_offset_bits=64; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cv_sys_file_offset_bits=unknown + break +done +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_file_offset_bits" >&5 +$as_echo "$ac_cv_sys_file_offset_bits" >&6; } +case $ac_cv_sys_file_offset_bits in #( + no | unknown) ;; + *) +cat >>confdefs.h <<_ACEOF +#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits +_ACEOF +;; +esac +rm -rf conftest* + if test $ac_cv_sys_file_offset_bits = unknown; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGE_FILES value needed for large files" >&5 +$as_echo_n "checking for _LARGE_FILES value needed for large files... " >&6; } +if ${ac_cv_sys_large_files+:} false; then : + $as_echo_n "(cached) " >&6 +else + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/types.h> + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_large_files=no; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#define _LARGE_FILES 1 +#include <sys/types.h> + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_large_files=1; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cv_sys_large_files=unknown + break +done +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_large_files" >&5 +$as_echo "$ac_cv_sys_large_files" >&6; } +case $ac_cv_sys_large_files in #( + no | unknown) ;; + *) +cat >>confdefs.h <<_ACEOF +#define _LARGE_FILES $ac_cv_sys_large_files +_ACEOF +;; +esac +rm -rf conftest* + fi + + +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdarg.h> +#include <stdio.h> +struct stat; +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 +$as_echo_n "checking whether $CC understands -c and -o together... " >&6; } +if ${am_cv_prog_cc_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 + ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 +$as_echo "$am_cv_prog_cc_c_o" >&6; } +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +depcc="$CC" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CC_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + +am_cv_prog_cc_stdc=$ac_cv_prog_cc_stdc + + +# We require a C++11 compiler. Check if one is available, and if +# necessary, set CXX_DIALECT to some -std=xxx switch. + + ax_cxx_compile_alternatives="11 0x" ax_cxx_compile_cxx11_required=true + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + CXX_DIALECT="" + ac_success=no + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++11 features by default" >&5 +$as_echo_n "checking whether $CXX supports C++11 features by default... " >&6; } +if ${ax_cv_cxx_compile_cxx11+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +// If the compiler admits that it is not ready for C++11, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201103L + +#error "This is not a C++11 compiler" + +#else + +namespace cxx11 +{ + + namespace test_static_assert + { + + template <typename T> + struct check + { + static_assert(sizeof(int) <= sizeof(T), "not big enough"); + }; + + } + + namespace test_final_override + { + + struct Base + { + virtual void f() {} + }; + + struct Derived : public Base + { + virtual void f() override {} + }; + + } + + namespace test_double_right_angle_brackets + { + + template < typename T > + struct check {}; + + typedef check<void> single_type; + typedef check<check<void>> double_type; + typedef check<check<check<void>>> triple_type; + typedef check<check<check<check<void>>>> quadruple_type; + + } + + namespace test_decltype + { + + int + f() + { + int a = 1; + decltype(a) b = 2; + return a + b; + } + + } + + namespace test_type_deduction + { + + template < typename T1, typename T2 > + struct is_same + { + static const bool value = false; + }; + + template < typename T > + struct is_same<T, T> + { + static const bool value = true; + }; + + template < typename T1, typename T2 > + auto + add(T1 a1, T2 a2) -> decltype(a1 + a2) + { + return a1 + a2; + } + + int + test(const int c, volatile int v) + { + static_assert(is_same<int, decltype(0)>::value == true, ""); + static_assert(is_same<int, decltype(c)>::value == false, ""); + static_assert(is_same<int, decltype(v)>::value == false, ""); + auto ac = c; + auto av = v; + auto sumi = ac + av + 'x'; + auto sumf = ac + av + 1.0; + static_assert(is_same<int, decltype(ac)>::value == true, ""); + static_assert(is_same<int, decltype(av)>::value == true, ""); + static_assert(is_same<int, decltype(sumi)>::value == true, ""); + static_assert(is_same<int, decltype(sumf)>::value == false, ""); + static_assert(is_same<int, decltype(add(c, v))>::value == true, ""); + return (sumf > 0.0) ? sumi : add(c, v); + } + + } + + namespace test_noexcept + { + + int f() { return 0; } + int g() noexcept { return 0; } + + static_assert(noexcept(f()) == false, ""); + static_assert(noexcept(g()) == true, ""); + + } + + namespace test_constexpr + { + + template < typename CharT > + unsigned long constexpr + strlen_c_r(const CharT *const s, const unsigned long acc) noexcept + { + return *s ? strlen_c_r(s + 1, acc + 1) : acc; + } + + template < typename CharT > + unsigned long constexpr + strlen_c(const CharT *const s) noexcept + { + return strlen_c_r(s, 0UL); + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("1") == 1UL, ""); + static_assert(strlen_c("example") == 7UL, ""); + static_assert(strlen_c("another\0example") == 7UL, ""); + + } + + namespace test_rvalue_references + { + + template < int N > + struct answer + { + static constexpr int value = N; + }; + + answer<1> f(int&) { return answer<1>(); } + answer<2> f(const int&) { return answer<2>(); } + answer<3> f(int&&) { return answer<3>(); } + + void + test() + { + int i = 0; + const int c = 0; + static_assert(decltype(f(i))::value == 1, ""); + static_assert(decltype(f(c))::value == 2, ""); + static_assert(decltype(f(0))::value == 3, ""); + } + + } + + namespace test_uniform_initialization + { + + struct test + { + static const int zero {}; + static const int one {1}; + }; + + static_assert(test::zero == 0, ""); + static_assert(test::one == 1, ""); + + } + + namespace test_lambdas + { + + void + test1() + { + auto lambda1 = [](){}; + auto lambda2 = lambda1; + lambda1(); + lambda2(); + } + + int + test2() + { + auto a = [](int i, int j){ return i + j; }(1, 2); + auto b = []() -> int { return '0'; }(); + auto c = [=](){ return a + b; }(); + auto d = [&](){ return c; }(); + auto e = [a, &b](int x) mutable { + const auto identity = [](int y){ return y; }; + for (auto i = 0; i < a; ++i) + a += b--; + return x + identity(a + b); + }(0); + return a + b + c + d + e; + } + + int + test3() + { + const auto nullary = [](){ return 0; }; + const auto unary = [](int x){ return x; }; + using nullary_t = decltype(nullary); + using unary_t = decltype(unary); + const auto higher1st = [](nullary_t f){ return f(); }; + const auto higher2nd = [unary](nullary_t f1){ + return [unary, f1](unary_t f2){ return f2(unary(f1())); }; + }; + return higher1st(nullary) + higher2nd(nullary)(unary); + } + + } + + namespace test_variadic_templates + { + + template <int...> + struct sum; + + template <int N0, int... N1toN> + struct sum<N0, N1toN...> + { + static constexpr auto value = N0 + sum<N1toN...>::value; + }; + + template <> + struct sum<> + { + static constexpr auto value = 0; + }; + + static_assert(sum<>::value == 0, ""); + static_assert(sum<1>::value == 1, ""); + static_assert(sum<23>::value == 23, ""); + static_assert(sum<1, 2>::value == 3, ""); + static_assert(sum<5, 5, 11>::value == 21, ""); + static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); + + } + + // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae + // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function + // because of this. + namespace test_template_alias_sfinae + { + + struct foo {}; + + template<typename T> + using member = typename T::member_type; + + template<typename T> + void func(...) {} + + template<typename T> + void func(member<T>*) {} + + void test(); + + void test() { func<foo>(0); } + + } + +} // namespace cxx11 + +#endif // __cplusplus >= 201103L + + + +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ax_cv_cxx_compile_cxx11=yes +else + ax_cv_cxx_compile_cxx11=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_cxx_compile_cxx11" >&5 +$as_echo "$ax_cv_cxx_compile_cxx11" >&6; } + if test x$ax_cv_cxx_compile_cxx11 = xyes; then + ac_success=yes + fi + + if test x$ac_success = xno; then + for alternative in ${ax_cxx_compile_alternatives}; do + switch="-std=gnu++${alternative}" + cachevar=`$as_echo "ax_cv_cxx_compile_cxx11_$switch" | $as_tr_sh` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++11 features with $switch" >&5 +$as_echo_n "checking whether $CXX supports C++11 features with $switch... " >&6; } +if eval \${$cachevar+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_CXX="$CXX" + CXX="$CXX $switch" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +// If the compiler admits that it is not ready for C++11, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201103L + +#error "This is not a C++11 compiler" + +#else + +namespace cxx11 +{ + + namespace test_static_assert + { + + template <typename T> + struct check + { + static_assert(sizeof(int) <= sizeof(T), "not big enough"); + }; + + } + + namespace test_final_override + { + + struct Base + { + virtual void f() {} + }; + + struct Derived : public Base + { + virtual void f() override {} + }; + + } + + namespace test_double_right_angle_brackets + { + + template < typename T > + struct check {}; + + typedef check<void> single_type; + typedef check<check<void>> double_type; + typedef check<check<check<void>>> triple_type; + typedef check<check<check<check<void>>>> quadruple_type; + + } + + namespace test_decltype + { + + int + f() + { + int a = 1; + decltype(a) b = 2; + return a + b; + } + + } + + namespace test_type_deduction + { + + template < typename T1, typename T2 > + struct is_same + { + static const bool value = false; + }; + + template < typename T > + struct is_same<T, T> + { + static const bool value = true; + }; + + template < typename T1, typename T2 > + auto + add(T1 a1, T2 a2) -> decltype(a1 + a2) + { + return a1 + a2; + } + + int + test(const int c, volatile int v) + { + static_assert(is_same<int, decltype(0)>::value == true, ""); + static_assert(is_same<int, decltype(c)>::value == false, ""); + static_assert(is_same<int, decltype(v)>::value == false, ""); + auto ac = c; + auto av = v; + auto sumi = ac + av + 'x'; + auto sumf = ac + av + 1.0; + static_assert(is_same<int, decltype(ac)>::value == true, ""); + static_assert(is_same<int, decltype(av)>::value == true, ""); + static_assert(is_same<int, decltype(sumi)>::value == true, ""); + static_assert(is_same<int, decltype(sumf)>::value == false, ""); + static_assert(is_same<int, decltype(add(c, v))>::value == true, ""); + return (sumf > 0.0) ? sumi : add(c, v); + } + + } + + namespace test_noexcept + { + + int f() { return 0; } + int g() noexcept { return 0; } + + static_assert(noexcept(f()) == false, ""); + static_assert(noexcept(g()) == true, ""); + + } + + namespace test_constexpr + { + + template < typename CharT > + unsigned long constexpr + strlen_c_r(const CharT *const s, const unsigned long acc) noexcept + { + return *s ? strlen_c_r(s + 1, acc + 1) : acc; + } + + template < typename CharT > + unsigned long constexpr + strlen_c(const CharT *const s) noexcept + { + return strlen_c_r(s, 0UL); + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("1") == 1UL, ""); + static_assert(strlen_c("example") == 7UL, ""); + static_assert(strlen_c("another\0example") == 7UL, ""); + + } + + namespace test_rvalue_references + { + + template < int N > + struct answer + { + static constexpr int value = N; + }; + + answer<1> f(int&) { return answer<1>(); } + answer<2> f(const int&) { return answer<2>(); } + answer<3> f(int&&) { return answer<3>(); } + + void + test() + { + int i = 0; + const int c = 0; + static_assert(decltype(f(i))::value == 1, ""); + static_assert(decltype(f(c))::value == 2, ""); + static_assert(decltype(f(0))::value == 3, ""); + } + + } + + namespace test_uniform_initialization + { + + struct test + { + static const int zero {}; + static const int one {1}; + }; + + static_assert(test::zero == 0, ""); + static_assert(test::one == 1, ""); + + } + + namespace test_lambdas + { + + void + test1() + { + auto lambda1 = [](){}; + auto lambda2 = lambda1; + lambda1(); + lambda2(); + } + + int + test2() + { + auto a = [](int i, int j){ return i + j; }(1, 2); + auto b = []() -> int { return '0'; }(); + auto c = [=](){ return a + b; }(); + auto d = [&](){ return c; }(); + auto e = [a, &b](int x) mutable { + const auto identity = [](int y){ return y; }; + for (auto i = 0; i < a; ++i) + a += b--; + return x + identity(a + b); + }(0); + return a + b + c + d + e; + } + + int + test3() + { + const auto nullary = [](){ return 0; }; + const auto unary = [](int x){ return x; }; + using nullary_t = decltype(nullary); + using unary_t = decltype(unary); + const auto higher1st = [](nullary_t f){ return f(); }; + const auto higher2nd = [unary](nullary_t f1){ + return [unary, f1](unary_t f2){ return f2(unary(f1())); }; + }; + return higher1st(nullary) + higher2nd(nullary)(unary); + } + + } + + namespace test_variadic_templates + { + + template <int...> + struct sum; + + template <int N0, int... N1toN> + struct sum<N0, N1toN...> + { + static constexpr auto value = N0 + sum<N1toN...>::value; + }; + + template <> + struct sum<> + { + static constexpr auto value = 0; + }; + + static_assert(sum<>::value == 0, ""); + static_assert(sum<1>::value == 1, ""); + static_assert(sum<23>::value == 23, ""); + static_assert(sum<1, 2>::value == 3, ""); + static_assert(sum<5, 5, 11>::value == 21, ""); + static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); + + } + + // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae + // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function + // because of this. + namespace test_template_alias_sfinae + { + + struct foo {}; + + template<typename T> + using member = typename T::member_type; + + template<typename T> + void func(...) {} + + template<typename T> + void func(member<T>*) {} + + void test(); + + void test() { func<foo>(0); } + + } + +} // namespace cxx11 + +#endif // __cplusplus >= 201103L + + + +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + eval $cachevar=yes +else + eval $cachevar=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CXX="$ac_save_CXX" +fi +eval ac_res=\$$cachevar + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + if eval test x\$$cachevar = xyes; then + CXX_DIALECT="$switch" + ac_success=yes + break + fi + done + fi + + if test x$ac_success = xno; then + for alternative in ${ax_cxx_compile_alternatives}; do + for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do + cachevar=`$as_echo "ax_cv_cxx_compile_cxx11_$switch" | $as_tr_sh` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++11 features with $switch" >&5 +$as_echo_n "checking whether $CXX supports C++11 features with $switch... " >&6; } +if eval \${$cachevar+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_CXX="$CXX" + CXX="$CXX $switch" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +// If the compiler admits that it is not ready for C++11, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201103L + +#error "This is not a C++11 compiler" + +#else + +namespace cxx11 +{ + + namespace test_static_assert + { + + template <typename T> + struct check + { + static_assert(sizeof(int) <= sizeof(T), "not big enough"); + }; + + } + + namespace test_final_override + { + + struct Base + { + virtual void f() {} + }; + + struct Derived : public Base + { + virtual void f() override {} + }; + + } + + namespace test_double_right_angle_brackets + { + + template < typename T > + struct check {}; + + typedef check<void> single_type; + typedef check<check<void>> double_type; + typedef check<check<check<void>>> triple_type; + typedef check<check<check<check<void>>>> quadruple_type; + + } + + namespace test_decltype + { + + int + f() + { + int a = 1; + decltype(a) b = 2; + return a + b; + } + + } + + namespace test_type_deduction + { + + template < typename T1, typename T2 > + struct is_same + { + static const bool value = false; + }; + + template < typename T > + struct is_same<T, T> + { + static const bool value = true; + }; + + template < typename T1, typename T2 > + auto + add(T1 a1, T2 a2) -> decltype(a1 + a2) + { + return a1 + a2; + } + + int + test(const int c, volatile int v) + { + static_assert(is_same<int, decltype(0)>::value == true, ""); + static_assert(is_same<int, decltype(c)>::value == false, ""); + static_assert(is_same<int, decltype(v)>::value == false, ""); + auto ac = c; + auto av = v; + auto sumi = ac + av + 'x'; + auto sumf = ac + av + 1.0; + static_assert(is_same<int, decltype(ac)>::value == true, ""); + static_assert(is_same<int, decltype(av)>::value == true, ""); + static_assert(is_same<int, decltype(sumi)>::value == true, ""); + static_assert(is_same<int, decltype(sumf)>::value == false, ""); + static_assert(is_same<int, decltype(add(c, v))>::value == true, ""); + return (sumf > 0.0) ? sumi : add(c, v); + } + + } + + namespace test_noexcept + { + + int f() { return 0; } + int g() noexcept { return 0; } + + static_assert(noexcept(f()) == false, ""); + static_assert(noexcept(g()) == true, ""); + + } + + namespace test_constexpr + { + + template < typename CharT > + unsigned long constexpr + strlen_c_r(const CharT *const s, const unsigned long acc) noexcept + { + return *s ? strlen_c_r(s + 1, acc + 1) : acc; + } + + template < typename CharT > + unsigned long constexpr + strlen_c(const CharT *const s) noexcept + { + return strlen_c_r(s, 0UL); + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("1") == 1UL, ""); + static_assert(strlen_c("example") == 7UL, ""); + static_assert(strlen_c("another\0example") == 7UL, ""); + + } + + namespace test_rvalue_references + { + + template < int N > + struct answer + { + static constexpr int value = N; + }; + + answer<1> f(int&) { return answer<1>(); } + answer<2> f(const int&) { return answer<2>(); } + answer<3> f(int&&) { return answer<3>(); } + + void + test() + { + int i = 0; + const int c = 0; + static_assert(decltype(f(i))::value == 1, ""); + static_assert(decltype(f(c))::value == 2, ""); + static_assert(decltype(f(0))::value == 3, ""); + } + + } + + namespace test_uniform_initialization + { + + struct test + { + static const int zero {}; + static const int one {1}; + }; + + static_assert(test::zero == 0, ""); + static_assert(test::one == 1, ""); + + } + + namespace test_lambdas + { + + void + test1() + { + auto lambda1 = [](){}; + auto lambda2 = lambda1; + lambda1(); + lambda2(); + } + + int + test2() + { + auto a = [](int i, int j){ return i + j; }(1, 2); + auto b = []() -> int { return '0'; }(); + auto c = [=](){ return a + b; }(); + auto d = [&](){ return c; }(); + auto e = [a, &b](int x) mutable { + const auto identity = [](int y){ return y; }; + for (auto i = 0; i < a; ++i) + a += b--; + return x + identity(a + b); + }(0); + return a + b + c + d + e; + } + + int + test3() + { + const auto nullary = [](){ return 0; }; + const auto unary = [](int x){ return x; }; + using nullary_t = decltype(nullary); + using unary_t = decltype(unary); + const auto higher1st = [](nullary_t f){ return f(); }; + const auto higher2nd = [unary](nullary_t f1){ + return [unary, f1](unary_t f2){ return f2(unary(f1())); }; + }; + return higher1st(nullary) + higher2nd(nullary)(unary); + } + + } + + namespace test_variadic_templates + { + + template <int...> + struct sum; + + template <int N0, int... N1toN> + struct sum<N0, N1toN...> + { + static constexpr auto value = N0 + sum<N1toN...>::value; + }; + + template <> + struct sum<> + { + static constexpr auto value = 0; + }; + + static_assert(sum<>::value == 0, ""); + static_assert(sum<1>::value == 1, ""); + static_assert(sum<23>::value == 23, ""); + static_assert(sum<1, 2>::value == 3, ""); + static_assert(sum<5, 5, 11>::value == 21, ""); + static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); + + } + + // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae + // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function + // because of this. + namespace test_template_alias_sfinae + { + + struct foo {}; + + template<typename T> + using member = typename T::member_type; + + template<typename T> + void func(...) {} + + template<typename T> + void func(member<T>*) {} + + void test(); + + void test() { func<foo>(0); } + + } + +} // namespace cxx11 + +#endif // __cplusplus >= 201103L + + + +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + eval $cachevar=yes +else + eval $cachevar=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CXX="$ac_save_CXX" +fi +eval ac_res=\$$cachevar + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + if eval test x\$$cachevar = xyes; then + CXX_DIALECT="$switch" + ac_success=yes + break + fi + done + if test x$ac_success = xyes; then + break + fi + done + fi + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + if test x$ax_cxx_compile_cxx11_required = xtrue; then + if test x$ac_success = xno; then + as_fn_error $? "*** A compiler with support for C++11 language features is required." "$LINENO" 5 + fi + fi + if test x$ac_success = xno; then + HAVE_CXX11=0 + { $as_echo "$as_me:${as_lineno-$LINENO}: No compiler with C++11 support was found" >&5 +$as_echo "$as_me: No compiler with C++11 support was found" >&6;} + else + HAVE_CXX11=1 + +$as_echo "#define HAVE_CXX11 1" >>confdefs.h + + fi + + + + +# If we haven't got the data from the intl directory, +# assume NLS is disabled. +USE_NLS=no +LIBINTL= +LIBINTL_DEP= +INCINTL= +XGETTEXT= +GMSGFMT= +POSUB= + +if test -f ../intl/config.intl; then + . ../intl/config.intl +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether NLS is requested" >&5 +$as_echo_n "checking whether NLS is requested... " >&6; } +if test x"$USE_NLS" != xyes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define ENABLE_NLS 1" >>confdefs.h + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for catalogs to be installed" >&5 +$as_echo_n "checking for catalogs to be installed... " >&6; } + # Look for .po and .gmo files in the source directory. + CATALOGS= + XLINGUAS= + for cat in $srcdir/po/*.gmo $srcdir/po/*.po; do + # If there aren't any .gmo files the shell will give us the + # literal string "../path/to/srcdir/po/*.gmo" which has to be + # weeded out. + case "$cat" in *\**) + continue;; + esac + # The quadruple backslash is collapsed to a double backslash + # by the backticks, then collapsed again by the double quotes, + # leaving us with one backslash in the sed expression (right + # before the dot that mustn't act as a wildcard). + cat=`echo $cat | sed -e "s!$srcdir/po/!!" -e "s!\\\\.po!.gmo!"` + lang=`echo $cat | sed -e "s!\\\\.gmo!!"` + # The user is allowed to set LINGUAS to a list of languages to + # install catalogs for. If it's empty that means "all of them." + if test "x$LINGUAS" = x; then + CATALOGS="$CATALOGS $cat" + XLINGUAS="$XLINGUAS $lang" + else + case "$LINGUAS" in *$lang*) + CATALOGS="$CATALOGS $cat" + XLINGUAS="$XLINGUAS $lang" + ;; + esac + fi + done + LINGUAS="$XLINGUAS" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LINGUAS" >&5 +$as_echo "$LINGUAS" >&6; } + + + DATADIRNAME=share + + INSTOBJEXT=.mo + + GENCAT=gencat + + CATOBJEXT=.gmo + +fi + + + # Check for presence and size of long long. + ac_fn_c_check_type "$LINENO" "long long" "ac_cv_type_long_long" "$ac_includes_default" +if test "x$ac_cv_type_long_long" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_LONG_LONG 1 +_ACEOF + +# The cast to long int 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. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long long" >&5 +$as_echo_n "checking size of long long... " >&6; } +if ${ac_cv_sizeof_long_long+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long long))" "ac_cv_sizeof_long_long" "$ac_includes_default"; then : + +else + if test "$ac_cv_type_long_long" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (long long) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_long_long=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long_long" >&5 +$as_echo "$ac_cv_sizeof_long_long" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_LONG_LONG $ac_cv_sizeof_long_long +_ACEOF + + +fi + + + as_ac_Symbol=`$as_echo "ac_cv_have_decl_basename(char *)" | $as_tr_sh` +ac_fn_c_check_decl "$LINENO" "basename(char *)" "$as_ac_Symbol" "$ac_includes_default" +if eval test \"x\$"$as_ac_Symbol"\" = x"yes"; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_BASENAME $ac_have_decl +_ACEOF +ac_fn_c_check_decl "$LINENO" "ffs" "ac_cv_have_decl_ffs" "$ac_includes_default" +if test "x$ac_cv_have_decl_ffs" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_FFS $ac_have_decl +_ACEOF +ac_fn_c_check_decl "$LINENO" "asprintf" "ac_cv_have_decl_asprintf" "$ac_includes_default" +if test "x$ac_cv_have_decl_asprintf" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_ASPRINTF $ac_have_decl +_ACEOF +ac_fn_c_check_decl "$LINENO" "vasprintf" "ac_cv_have_decl_vasprintf" "$ac_includes_default" +if test "x$ac_cv_have_decl_vasprintf" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_VASPRINTF $ac_have_decl +_ACEOF +ac_fn_c_check_decl "$LINENO" "snprintf" "ac_cv_have_decl_snprintf" "$ac_includes_default" +if test "x$ac_cv_have_decl_snprintf" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_SNPRINTF $ac_have_decl +_ACEOF +ac_fn_c_check_decl "$LINENO" "vsnprintf" "ac_cv_have_decl_vsnprintf" "$ac_includes_default" +if test "x$ac_cv_have_decl_vsnprintf" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_VSNPRINTF $ac_have_decl +_ACEOF + + ac_fn_c_check_decl "$LINENO" "strtol" "ac_cv_have_decl_strtol" "$ac_includes_default" +if test "x$ac_cv_have_decl_strtol" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_STRTOL $ac_have_decl +_ACEOF +ac_fn_c_check_decl "$LINENO" "strtoul" "ac_cv_have_decl_strtoul" "$ac_includes_default" +if test "x$ac_cv_have_decl_strtoul" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_STRTOUL $ac_have_decl +_ACEOF +ac_fn_c_check_decl "$LINENO" "strtoll" "ac_cv_have_decl_strtoll" "$ac_includes_default" +if test "x$ac_cv_have_decl_strtoll" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_STRTOLL $ac_have_decl +_ACEOF +ac_fn_c_check_decl "$LINENO" "strtoull" "ac_cv_have_decl_strtoull" "$ac_includes_default" +if test "x$ac_cv_have_decl_strtoull" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_STRTOULL $ac_have_decl +_ACEOF + + ac_fn_c_check_decl "$LINENO" "strverscmp" "ac_cv_have_decl_strverscmp" "$ac_includes_default" +if test "x$ac_cv_have_decl_strverscmp" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_STRVERSCMP $ac_have_decl +_ACEOF + + +ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" +if test "x$ac_cv_type_size_t" = xyes; then : + +else + +cat >>confdefs.h <<_ACEOF +#define size_t unsigned int +_ACEOF + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 +$as_echo_n "checking for a sed that does not truncate output... " >&6; } +if ${ac_cv_path_SED+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for ac_i in 1 2 3 4 5 6 7; do + ac_script="$ac_script$as_nl$ac_script" + done + echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed + { ac_script=; unset ac_script;} + if test -z "$SED"; then + ac_path_SED_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_SED" || continue +# Check for GNU ac_path_SED and select it if it is found. + # Check for GNU $ac_path_SED +case `"$ac_path_SED" --version 2>&1` in +*GNU*) + ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo '' >> "conftest.nl" + "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_SED_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_SED="$ac_path_SED" + ac_path_SED_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_SED_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_SED"; then + as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 + fi +else + ac_cv_path_SED=$SED +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 +$as_echo "$ac_cv_path_SED" >&6; } + SED="$ac_cv_path_SED" + rm -f conftest.sed + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <float.h> + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <string.h> + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdlib.h> + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <ctype.h> +#include <stdlib.h> +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + + # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works +# for constant arguments. Useless! +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working alloca.h" >&5 +$as_echo_n "checking for working alloca.h... " >&6; } +if ${ac_cv_working_alloca_h+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <alloca.h> +int +main () +{ +char *p = (char *) alloca (2 * sizeof (int)); + if (p) return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_working_alloca_h=yes +else + ac_cv_working_alloca_h=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_working_alloca_h" >&5 +$as_echo "$ac_cv_working_alloca_h" >&6; } +if test $ac_cv_working_alloca_h = yes; then + +$as_echo "#define HAVE_ALLOCA_H 1" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for alloca" >&5 +$as_echo_n "checking for alloca... " >&6; } +if ${ac_cv_func_alloca_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __GNUC__ +# define alloca __builtin_alloca +#else +# ifdef _MSC_VER +# include <malloc.h> +# define alloca _alloca +# else +# ifdef HAVE_ALLOCA_H +# include <alloca.h> +# else +# ifdef _AIX + #pragma alloca +# else +# ifndef alloca /* predefined by HP cc +Olibcalls */ +void *alloca (size_t); +# endif +# endif +# endif +# endif +#endif + +int +main () +{ +char *p = (char *) alloca (1); + if (p) return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_func_alloca_works=yes +else + ac_cv_func_alloca_works=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_alloca_works" >&5 +$as_echo "$ac_cv_func_alloca_works" >&6; } + +if test $ac_cv_func_alloca_works = yes; then + +$as_echo "#define HAVE_ALLOCA 1" >>confdefs.h + +else + # The SVR3 libPW and SVR4 libucb both contain incompatible functions +# that cause trouble. Some versions do not even contain alloca or +# contain a buggy version. If you still want to use their alloca, +# use ar to extract alloca.o from them instead of compiling alloca.c. + +ALLOCA=\${LIBOBJDIR}alloca.$ac_objext + +$as_echo "#define C_ALLOCA 1" >>confdefs.h + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether \`alloca.c' needs Cray hooks" >&5 +$as_echo_n "checking whether \`alloca.c' needs Cray hooks... " >&6; } +if ${ac_cv_os_cray+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#if defined CRAY && ! defined CRAY2 +webecray +#else +wenotbecray +#endif + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "webecray" >/dev/null 2>&1; then : + ac_cv_os_cray=yes +else + ac_cv_os_cray=no +fi +rm -f conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_os_cray" >&5 +$as_echo "$ac_cv_os_cray" >&6; } +if test $ac_cv_os_cray = yes; then + for ac_func in _getb67 GETB67 getb67; do + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + +cat >>confdefs.h <<_ACEOF +#define CRAY_STACKSEG_END $ac_func +_ACEOF + + break +fi + + done +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking stack direction for C alloca" >&5 +$as_echo_n "checking stack direction for C alloca... " >&6; } +if ${ac_cv_c_stack_direction+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + ac_cv_c_stack_direction=0 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +find_stack_direction (int *addr, int depth) +{ + int dir, dummy = 0; + if (! addr) + addr = &dummy; + *addr = addr < &dummy ? 1 : addr == &dummy ? 0 : -1; + dir = depth ? find_stack_direction (addr, depth - 1) : 0; + return dir + dummy; +} + +int +main (int argc, char **argv) +{ + return find_stack_direction (0, argc + !argv + 20) < 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_c_stack_direction=1 +else + ac_cv_c_stack_direction=-1 +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_stack_direction" >&5 +$as_echo "$ac_cv_c_stack_direction" >&6; } +cat >>confdefs.h <<_ACEOF +#define STACK_DIRECTION $ac_cv_c_stack_direction +_ACEOF + + +fi + + + WIN32APILIBS= + case ${host} in + *mingw32*) + +$as_echo "#define USE_WIN32API 1" >>confdefs.h + + WIN32APILIBS="-lws2_32" + ;; + esac + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for nl_langinfo and CODESET" >&5 +$as_echo_n "checking for nl_langinfo and CODESET... " >&6; } +if ${am_cv_langinfo_codeset+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <langinfo.h> +int +main () +{ +char* cs = nl_langinfo(CODESET); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + am_cv_langinfo_codeset=yes +else + am_cv_langinfo_codeset=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_langinfo_codeset" >&5 +$as_echo "$am_cv_langinfo_codeset" >&6; } + if test $am_cv_langinfo_codeset = yes; then + +$as_echo "#define HAVE_LANGINFO_CODESET 1" >>confdefs.h + + fi + + + for ac_header in linux/perf_event.h locale.h memory.h signal.h sys/resource.h sys/socket.h sys/un.h sys/wait.h thread_db.h wait.h termios.h dlfcn.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + for ac_func in fdwalk getrlimit pipe pipe2 socketpair sigaction \ + sigprocmask +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + + ac_fn_c_check_decl "$LINENO" "strstr" "ac_cv_have_decl_strstr" "$ac_includes_default" +if test "x$ac_cv_have_decl_strstr" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_STRSTR $ac_have_decl +_ACEOF + + + # Check for std::thread. This does not work on some platforms, like + # mingw and DJGPP. + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +ax_pthread_ok=no + +# We used to check for pthread.h first, but this fails if pthread.h +# requires special compiler flags (e.g. on Tru64 or Sequent). +# It gets checked for in the link test anyway. + +# First of all, check if the user has set any of the PTHREAD_LIBS, +# etcetera environment variables, and if threads linking works using +# them: +if test "x$PTHREAD_CFLAGS$PTHREAD_LIBS" != "x"; then + ax_pthread_save_CC="$CC" + ax_pthread_save_CFLAGS="$CFLAGS" + ax_pthread_save_LIBS="$LIBS" + if test "x$PTHREAD_CC" != "x"; then : + CC="$PTHREAD_CC" +fi + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS" >&5 +$as_echo_n "checking for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char pthread_join (); +int +main () +{ +return pthread_join (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ax_pthread_ok=yes +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_ok" >&5 +$as_echo "$ax_pthread_ok" >&6; } + if test "x$ax_pthread_ok" = "xno"; then + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" + fi + CC="$ax_pthread_save_CC" + CFLAGS="$ax_pthread_save_CFLAGS" + LIBS="$ax_pthread_save_LIBS" +fi + +# We must check for the threads library under a number of different +# names; the ordering is very important because some systems +# (e.g. DEC) have both -lpthread and -lpthreads, where one of the +# libraries is broken (non-POSIX). + +# Create a list of thread flags to try. Items starting with a "-" are +# C compiler flags, and other items are library names, except for "none" +# which indicates that we try without any flags at all, and "pthread-config" +# which is a program returning the flags for the Pth emulation library. + +ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" + +# The ordering *is* (sometimes) important. Some notes on the +# individual items follow: + +# pthreads: AIX (must check this before -lpthread) +# none: in case threads are in libc; should be tried before -Kthread and +# other compiler flags to prevent continual compiler warnings +# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) +# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads), Tru64 +# (Note: HP C rejects this with "bad form for `-t' option") +# -pthreads: Solaris/gcc (Note: HP C also rejects) +# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it +# doesn't hurt to check since this sometimes defines pthreads and +# -D_REENTRANT too), HP C (must be checked before -lpthread, which +# is present but should not be used directly; and before -mthreads, +# because the compiler interprets this as "-mt" + "-hreads") +# -mthreads: Mingw32/gcc, Lynx/gcc +# pthread: Linux, etcetera +# --thread-safe: KAI C++ +# pthread-config: use pthread-config program (for GNU Pth library) + +case $host_os in + + freebsd*) + + # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) + # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) + + ax_pthread_flags="-kthread lthread $ax_pthread_flags" + ;; + + hpux*) + + # From the cc(1) man page: "[-mt] Sets various -D flags to enable + # multi-threading and also sets -lpthread." + + ax_pthread_flags="-mt -pthread pthread $ax_pthread_flags" + ;; + + openedition*) + + # IBM z/OS requires a feature-test macro to be defined in order to + # enable POSIX threads at all, so give the user a hint if this is + # not set. (We don't define these ourselves, as they can affect + # other portions of the system API in unpredictable ways.) + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +# if !defined(_OPEN_THREADS) && !defined(_UNIX03_THREADS) + AX_PTHREAD_ZOS_MISSING +# endif + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "AX_PTHREAD_ZOS_MISSING" >/dev/null 2>&1; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support." >&5 +$as_echo "$as_me: WARNING: IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support." >&2;} +fi +rm -f conftest* + + ;; + + solaris*) + + # On Solaris (at least, for some versions), libc contains stubbed + # (non-functional) versions of the pthreads routines, so link-based + # tests will erroneously succeed. (N.B.: The stubs are missing + # pthread_cleanup_push, or rather a function called by this macro, + # so we could check for that, but who knows whether they'll stub + # that too in a future libc.) So we'll check first for the + # standard Solaris way of linking pthreads (-mt -lpthread). + + ax_pthread_flags="-mt,pthread pthread $ax_pthread_flags" + ;; +esac + +# GCC generally uses -pthread, or -pthreads on some platforms (e.g. SPARC) + +if test "x$GCC" = "xyes"; then : + ax_pthread_flags="-pthread -pthreads $ax_pthread_flags" +fi + +# The presence of a feature test macro requesting re-entrant function +# definitions is, on some systems, a strong hint that pthreads support is +# correctly enabled + +case $host_os in + darwin* | hpux* | linux* | osf* | solaris*) + ax_pthread_check_macro="_REENTRANT" + ;; + + aix*) + ax_pthread_check_macro="_THREAD_SAFE" + ;; + + *) + ax_pthread_check_macro="--" + ;; +esac +if test "x$ax_pthread_check_macro" = "x--"; then : + ax_pthread_check_cond=0 +else + ax_pthread_check_cond="!defined($ax_pthread_check_macro)" +fi + +# Are we compiling with Clang? + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC is Clang" >&5 +$as_echo_n "checking whether $CC is Clang... " >&6; } +if ${ax_cv_PTHREAD_CLANG+:} false; then : + $as_echo_n "(cached) " >&6 +else + ax_cv_PTHREAD_CLANG=no + # Note that Autoconf sets GCC=yes for Clang as well as GCC + if test "x$GCC" = "xyes"; then + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Note: Clang 2.7 lacks __clang_[a-z]+__ */ +# if defined(__clang__) && defined(__llvm__) + AX_PTHREAD_CC_IS_CLANG +# endif + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "AX_PTHREAD_CC_IS_CLANG" >/dev/null 2>&1; then : + ax_cv_PTHREAD_CLANG=yes +fi +rm -f conftest* + + fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_CLANG" >&5 +$as_echo "$ax_cv_PTHREAD_CLANG" >&6; } +ax_pthread_clang="$ax_cv_PTHREAD_CLANG" + +ax_pthread_clang_warning=no + +# Clang needs special handling, because older versions handle the -pthread +# option in a rather... idiosyncratic way + +if test "x$ax_pthread_clang" = "xyes"; then + + # Clang takes -pthread; it has never supported any other flag + + # (Note 1: This will need to be revisited if a system that Clang + # supports has POSIX threads in a separate library. This tends not + # to be the way of modern systems, but it's conceivable.) + + # (Note 2: On some systems, notably Darwin, -pthread is not needed + # to get POSIX threads support; the API is always present and + # active. We could reasonably leave PTHREAD_CFLAGS empty. But + # -pthread does define _REENTRANT, and while the Darwin headers + # ignore this macro, third-party headers might not.) + + PTHREAD_CFLAGS="-pthread" + PTHREAD_LIBS= + + ax_pthread_ok=yes + + # However, older versions of Clang make a point of warning the user + # that, in an invocation where only linking and no compilation is + # taking place, the -pthread option has no effect ("argument unused + # during compilation"). They expect -pthread to be passed in only + # when source code is being compiled. + # + # Problem is, this is at odds with the way Automake and most other + # C build frameworks function, which is that the same flags used in + # compilation (CFLAGS) are also used in linking. Many systems + # supported by AX_PTHREAD require exactly this for POSIX threads + # support, and in fact it is often not straightforward to specify a + # flag that is used only in the compilation phase and not in + # linking. Such a scenario is extremely rare in practice. + # + # Even though use of the -pthread flag in linking would only print + # a warning, this can be a nuisance for well-run software projects + # that build with -Werror. So if the active version of Clang has + # this misfeature, we search for an option to squash it. + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether Clang needs flag to prevent \"argument unused\" warning when linking with -pthread" >&5 +$as_echo_n "checking whether Clang needs flag to prevent \"argument unused\" warning when linking with -pthread... " >&6; } +if ${ax_cv_PTHREAD_CLANG_NO_WARN_FLAG+:} false; then : + $as_echo_n "(cached) " >&6 +else + ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown + # Create an alternate version of $ac_link that compiles and + # links in two steps (.c -> .o, .o -> exe) instead of one + # (.c -> exe), because the warning occurs only in the second + # step + ax_pthread_save_ac_link="$ac_link" + ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g' + ax_pthread_link_step=`$as_echo "$ac_link" | sed "$ax_pthread_sed"` + ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)" + ax_pthread_save_CFLAGS="$CFLAGS" + for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do + if test "x$ax_pthread_try" = "xunknown"; then : + break +fi + CFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CFLAGS" + ac_link="$ax_pthread_save_ac_link" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int main(void){return 0;} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_link="$ax_pthread_2step_ac_link" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int main(void){return 0;} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + break +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + done + ac_link="$ax_pthread_save_ac_link" + CFLAGS="$ax_pthread_save_CFLAGS" + if test "x$ax_pthread_try" = "x"; then : + ax_pthread_try=no +fi + ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" >&5 +$as_echo "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" >&6; } + + case "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" in + no | unknown) ;; + *) PTHREAD_CFLAGS="$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG $PTHREAD_CFLAGS" ;; + esac + +fi # $ax_pthread_clang = yes + +if test "x$ax_pthread_ok" = "xno"; then +for ax_pthread_try_flag in $ax_pthread_flags; do + + case $ax_pthread_try_flag in + none) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work without any flags" >&5 +$as_echo_n "checking whether pthreads work without any flags... " >&6; } + ;; + + -mt,pthread) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work with -mt -lpthread" >&5 +$as_echo_n "checking whether pthreads work with -mt -lpthread... " >&6; } + PTHREAD_CFLAGS="-mt" + PTHREAD_LIBS="-lpthread" + ;; + + -*) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work with $ax_pthread_try_flag" >&5 +$as_echo_n "checking whether pthreads work with $ax_pthread_try_flag... " >&6; } + PTHREAD_CFLAGS="$ax_pthread_try_flag" + ;; + + pthread-config) + # Extract the first word of "pthread-config", so it can be a program name with args. +set dummy pthread-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ax_pthread_config+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ax_pthread_config"; then + ac_cv_prog_ax_pthread_config="$ax_pthread_config" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ax_pthread_config="yes" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_prog_ax_pthread_config" && ac_cv_prog_ax_pthread_config="no" +fi +fi +ax_pthread_config=$ac_cv_prog_ax_pthread_config +if test -n "$ax_pthread_config"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_config" >&5 +$as_echo "$ax_pthread_config" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + if test "x$ax_pthread_config" = "xno"; then : + continue +fi + PTHREAD_CFLAGS="`pthread-config --cflags`" + PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" + ;; + + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the pthreads library -l$ax_pthread_try_flag" >&5 +$as_echo_n "checking for the pthreads library -l$ax_pthread_try_flag... " >&6; } + PTHREAD_LIBS="-l$ax_pthread_try_flag" + ;; + esac + + ax_pthread_save_CFLAGS="$CFLAGS" + ax_pthread_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + + # Check for various functions. We must include pthread.h, + # since some functions may be macros. (On the Sequent, we + # need a special flag -Kthread to make this header compile.) + # We check for pthread_join because it is in -lpthread on IRIX + # while pthread_create is in libc. We check for pthread_attr_init + # due to DEC craziness with -lpthreads. We check for + # pthread_cleanup_push because it is one of the few pthread + # functions on Solaris that doesn't have a non-functional libc stub. + # We try pthread_create on general principles. + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <pthread.h> +# if $ax_pthread_check_cond +# error "$ax_pthread_check_macro must be defined" +# endif + static void routine(void *a) { a = 0; } + static void *start_routine(void *a) { return a; } +int +main () +{ +pthread_t th; pthread_attr_t attr; + pthread_create(&th, 0, start_routine, 0); + pthread_join(th, 0); + pthread_attr_init(&attr); + pthread_cleanup_push(routine, 0); + pthread_cleanup_pop(0) /* ; */ + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ax_pthread_ok=yes +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + + CFLAGS="$ax_pthread_save_CFLAGS" + LIBS="$ax_pthread_save_LIBS" + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_ok" >&5 +$as_echo "$ax_pthread_ok" >&6; } + if test "x$ax_pthread_ok" = "xyes"; then : + break +fi + + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" +done +fi + +# Various other checks: +if test "x$ax_pthread_ok" = "xyes"; then + ax_pthread_save_CFLAGS="$CFLAGS" + ax_pthread_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + + # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for joinable pthread attribute" >&5 +$as_echo_n "checking for joinable pthread attribute... " >&6; } +if ${ax_cv_PTHREAD_JOINABLE_ATTR+:} false; then : + $as_echo_n "(cached) " >&6 +else + ax_cv_PTHREAD_JOINABLE_ATTR=unknown + for ax_pthread_attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <pthread.h> +int +main () +{ +int attr = $ax_pthread_attr; return attr /* ; */ + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ax_cv_PTHREAD_JOINABLE_ATTR=$ax_pthread_attr; break +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + done + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_JOINABLE_ATTR" >&5 +$as_echo "$ax_cv_PTHREAD_JOINABLE_ATTR" >&6; } + if test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xunknown" && \ + test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xPTHREAD_CREATE_JOINABLE" && \ + test "x$ax_pthread_joinable_attr_defined" != "xyes"; then : + +cat >>confdefs.h <<_ACEOF +#define PTHREAD_CREATE_JOINABLE $ax_cv_PTHREAD_JOINABLE_ATTR +_ACEOF + + ax_pthread_joinable_attr_defined=yes + +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether more special flags are required for pthreads" >&5 +$as_echo_n "checking whether more special flags are required for pthreads... " >&6; } +if ${ax_cv_PTHREAD_SPECIAL_FLAGS+:} false; then : + $as_echo_n "(cached) " >&6 +else + ax_cv_PTHREAD_SPECIAL_FLAGS=no + case $host_os in + solaris*) + ax_cv_PTHREAD_SPECIAL_FLAGS="-D_POSIX_PTHREAD_SEMANTICS" + ;; + esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_SPECIAL_FLAGS" >&5 +$as_echo "$ax_cv_PTHREAD_SPECIAL_FLAGS" >&6; } + if test "x$ax_cv_PTHREAD_SPECIAL_FLAGS" != "xno" && \ + test "x$ax_pthread_special_flags_added" != "xyes"; then : + PTHREAD_CFLAGS="$ax_cv_PTHREAD_SPECIAL_FLAGS $PTHREAD_CFLAGS" + ax_pthread_special_flags_added=yes +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PTHREAD_PRIO_INHERIT" >&5 +$as_echo_n "checking for PTHREAD_PRIO_INHERIT... " >&6; } +if ${ax_cv_PTHREAD_PRIO_INHERIT+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <pthread.h> +int +main () +{ +int i = PTHREAD_PRIO_INHERIT; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ax_cv_PTHREAD_PRIO_INHERIT=yes +else + ax_cv_PTHREAD_PRIO_INHERIT=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_PRIO_INHERIT" >&5 +$as_echo "$ax_cv_PTHREAD_PRIO_INHERIT" >&6; } + if test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes" && \ + test "x$ax_pthread_prio_inherit_defined" != "xyes"; then : + +$as_echo "#define HAVE_PTHREAD_PRIO_INHERIT 1" >>confdefs.h + + ax_pthread_prio_inherit_defined=yes + +fi + + CFLAGS="$ax_pthread_save_CFLAGS" + LIBS="$ax_pthread_save_LIBS" + + # More AIX lossage: compile with *_r variant + if test "x$GCC" != "xyes"; then + case $host_os in + aix*) + case "x/$CC" in #( + x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6) : + #handle absolute path differently from PATH based program lookup + case "x$CC" in #( + x/*) : + if as_fn_executable_p ${CC}_r; then : + PTHREAD_CC="${CC}_r" +fi ;; #( + *) : + for ac_prog in ${CC}_r +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_PTHREAD_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$PTHREAD_CC"; then + ac_cv_prog_PTHREAD_CC="$PTHREAD_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_PTHREAD_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +PTHREAD_CC=$ac_cv_prog_PTHREAD_CC +if test -n "$PTHREAD_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PTHREAD_CC" >&5 +$as_echo "$PTHREAD_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$PTHREAD_CC" && break +done +test -n "$PTHREAD_CC" || PTHREAD_CC="$CC" + ;; +esac ;; #( + *) : + ;; +esac + ;; + esac + fi +fi + +test -n "$PTHREAD_CC" || PTHREAD_CC="$CC" + + + + + +# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: +if test "x$ax_pthread_ok" = "xyes"; then + threads=yes + : +else + ax_pthread_ok=no + threads=no +fi +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + + if test "$threads" = "yes"; then + save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" + save_CXXFLAGS="$CXXFLAGS" + CXXFLAGS="$PTHREAD_CFLAGS $save_CXXFLAGS" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for std::thread" >&5 +$as_echo_n "checking for std::thread... " >&6; } +if ${gdb_cv_cxx_std_thread+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <thread> + void callback() { } +int +main () +{ +std::thread t(callback); + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + gdb_cv_cxx_std_thread=yes +else + gdb_cv_cxx_std_thread=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gdb_cv_cxx_std_thread" >&5 +$as_echo "$gdb_cv_cxx_std_thread" >&6; } + + # This check must be here, while LIBS includes any necessary + # threading library. + for ac_func in pthread_sigmask pthread_setname_np +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_cxx_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + + LIBS="$save_LIBS" + CXXFLAGS="$save_CXXFLAGS" + fi + if test "$gdb_cv_cxx_std_thread" = "yes"; then + +$as_echo "#define CXX_STD_THREAD 1" >>confdefs.h + + fi + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sigsetjmp" >&5 +$as_echo_n "checking for sigsetjmp... " >&6; } +if ${gdb_cv_func_sigsetjmp+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include <setjmp.h> + +int +main () +{ +sigjmp_buf env; while (! sigsetjmp (env, 1)) siglongjmp (env, 1); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gdb_cv_func_sigsetjmp=yes +else + gdb_cv_func_sigsetjmp=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gdb_cv_func_sigsetjmp" >&5 +$as_echo "$gdb_cv_func_sigsetjmp" >&6; } +if test "$gdb_cv_func_sigsetjmp" = "yes"; then + +$as_echo "#define HAVE_SIGSETJMP 1" >>confdefs.h + +fi + + +# Check whether we will enable the inclusion of unit tests when +# compiling GDB. +# +# The default value of this option changes depending whether we're on +# development mode (in which case it's "true") or not (in which case +# it's "false"). +# Check whether --enable-unit-tests was given. +if test "${enable_unit_tests+set}" = set; then : + enableval=$enable_unit_tests; case "${enableval}" in + yes) enable_unittests=true ;; + no) enable_unittests=false ;; + *) as_fn_error $? "bad value ${enableval} for --{enable,disable}-unit-tests option" "$LINENO" 5 ;; +esac +else + enable_unittests=$development +fi + + +if $enable_unittests; then + +$as_echo "#define GDB_SELF_TEST 1" >>confdefs.h + + +fi + + if $enable_unittests; then + SELFTEST_TRUE= + SELFTEST_FALSE='#' +else + SELFTEST_TRUE='#' + SELFTEST_FALSE= +fi + + +TARGET_WORD_SIZE=`sed -n 's,#define BFD_ARCH_SIZE \(.*\)$,\1,p' ../bfd/bfd-in3.h` + +cat >>confdefs.h <<_ACEOF +#define TARGET_WORD_SIZE $TARGET_WORD_SIZE +_ACEOF + + +case ${host} in + *mingw32*) + +$as_echo "#define USE_WIN32API 1" >>confdefs.h + + ;; +esac + +ac_config_files="$ac_config_files Makefile" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + if test "x$cache_file" != "x/dev/null"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + +if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then + as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 +$as_echo_n "checking that generated files are newer than configure... " >&6; } + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 +$as_echo "done" >&6; } + if test -n "$EXEEXT"; then + am__EXEEXT_TRUE= + am__EXEEXT_FALSE='#' +else + am__EXEEXT_TRUE='#' + am__EXEEXT_FALSE= +fi + +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + as_fn_error $? "conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${SELFTEST_TRUE}" && test -z "${SELFTEST_FALSE}"; then + as_fn_error $? "conditional \"SELFTEST\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi + +: "${CONFIG_STATUS=./config.status}" +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by gdbsupport $as_me 1.0, which was +generated by GNU Autoconf 2.69. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to the package provider." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +ac_cs_version="\\ +gdbsupport config.status 1.0 +configured by $0, generated by GNU Autoconf 2.69, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2012 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +MKDIR_P='$MKDIR_P' +AWK='$AWK' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_HEADERS " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + as_fn_error $? "ambiguous option: \`$1' +Try \`$0 --help' for more information.";; + --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# +# INIT-COMMANDS +# +AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "support-config.h") CONFIG_HEADERS="$CONFIG_HEADERS support-config.h:config.in" ;; + "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' <conf$$subs.awk | sed ' +/^[^""]/{ + N + s/\n// +} +' >>$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$ac_tmp/defines.awk" <<\_ACAWK || +BEGIN { +_ACEOF + +# Transform confdefs.h into an awk script `defines.awk', embedded as +# here-document in config.status, that substitutes the proper values into +# config.h.in to produce config.h. + +# Create a delimiter string that does not exist in confdefs.h, to ease +# handling of long lines. +ac_delim='%!_!# ' +for ac_last_try in false false :; do + ac_tt=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_tt"; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +# For the awk script, D is an array of macro values keyed by name, +# likewise P contains macro parameters if any. Preserve backslash +# newline sequences. + +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +sed -n ' +s/.\{148\}/&'"$ac_delim"'/g +t rset +:rset +s/^[ ]*#[ ]*define[ ][ ]*/ / +t def +d +:def +s/\\$// +t bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3"/p +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +d +:bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3\\\\\\n"\\/p +t cont +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +t cont +d +:cont +n +s/.\{148\}/&'"$ac_delim"'/g +t clear +:clear +s/\\$// +t bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/"/p +d +:bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +b cont +' <confdefs.h | sed ' +s/'"$ac_delim"'/"\\\ +"/g' >>$CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { + line = \$ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #undef with comments. This is necessary, for example, + # in the case of _POSIX_SOURCE, which is predefined and required + # on some systems where configure will not decide to define it. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac + ac_MKDIR_P=$MKDIR_P + case $MKDIR_P in + [\\/$]* | ?:[\\/]* ) ;; + */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +s&@MKDIR_P@&$ac_MKDIR_P&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" + } >"$ac_tmp/config.h" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +$as_echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$ac_tmp/config.h" "$ac_file" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + fi + else + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ + || as_fn_error $? "could not create -" "$LINENO" 5 + fi +# Compute "$ac_file"'s index in $config_headers. +_am_arg="$ac_file" +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || +$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$_am_arg" : 'X\(//\)[^/]' \| \ + X"$_am_arg" : 'X\(//\)$' \| \ + X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$_am_arg" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'`/stamp-h$_am_stamp_count + ;; + + :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 +$as_echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "depfiles":C) test x"$AMDEP_TRUE" != x"" || { + # Older Autoconf quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named 'Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`$as_dirname -- "$mf" || +$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$mf" : 'X\(//\)[^/]' \| \ + X"$mf" : 'X\(//\)$' \| \ + X"$mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running 'make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "$am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`$as_dirname -- "$file" || +$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$file" : 'X\(//\)[^/]' \| \ + X"$file" : 'X\(//\)$' \| \ + X"$file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir=$dirpart/$fdir; as_fn_mkdir_p + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} + ;; + + esac +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit 1 +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + diff --git a/gdbsupport/configure.ac b/gdbsupport/configure.ac new file mode 100644 index 0000000..1dfed3c --- /dev/null +++ b/gdbsupport/configure.ac @@ -0,0 +1,63 @@ +dnl Autoconf configure script for GDB support library +dnl Copyright (C) 2020 Free Software Foundation, Inc. +dnl +dnl This program is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 3 of the License, or +dnl (at your option) any later version. +dnl +dnl This program is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with this program. If not, see <http://www.gnu.org/licenses/>. + +dnl Process this file with autoconf to produce a configure script. + +AC_INIT([gdbsupport], 1.0) +AC_CONFIG_SRCDIR(common-defs.h) +AC_CONFIG_HEADER(support-config.h:config.in) +AC_CANONICAL_SYSTEM +AM_MAINTAINER_MODE +AC_CONFIG_AUX_DIR(..) +AM_INIT_AUTOMAKE +AM_SILENT_RULES([yes]) + +AC_PROG_CC +AC_PROG_CXX +AC_PROG_RANLIB + +AC_USE_SYSTEM_EXTENSIONS +ACX_LARGEFILE +AM_PROG_CC_STDC + +# We require a C++11 compiler. Check if one is available, and if +# necessary, set CXX_DIALECT to some -std=xxx switch. +AX_CXX_COMPILE_STDCXX(11, , mandatory) + +dnl Set up for gettext. +ZW_GNU_GETTEXT_SISTER_DIR + +libiberty_INIT +GDB_AC_COMMON +GDB_AC_SELFTEST +AM_CONDITIONAL(SELFTEST, $enable_unittests) + +TARGET_WORD_SIZE=`sed -n 's,#define BFD_ARCH_SIZE \(.*\)$,\1,p' ../bfd/bfd-in3.h` +AC_DEFINE_UNQUOTED(TARGET_WORD_SIZE, $TARGET_WORD_SIZE, + [Define to the word size for the target.]) + +case ${host} in + *mingw32*) + AC_DEFINE(USE_WIN32API, 1, + [Define if we should use the Windows API, instead of the + POSIX API. On Windows, we use the Windows API when + building for MinGW, but the POSIX API when building + for Cygwin.]) + ;; +esac + +AC_CONFIG_FILES([Makefile]) +AC_OUTPUT diff --git a/gdbsupport/create-version.sh b/gdbsupport/create-version.sh new file mode 100755 index 0000000..81d6dbf --- /dev/null +++ b/gdbsupport/create-version.sh @@ -0,0 +1,38 @@ +#!/bin/sh + +# Copyright (C) 1989-2020 Free Software Foundation, Inc. + +# This file is part of GDB. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# Create version.c from version.in. +# Usage: +# create-version.sh PATH-TO-GDB-SRCDIR HOST_ALIAS \ +# TARGET_ALIAS OUTPUT-FILE-NAME + +srcdir="$1" +host_alias="$2" +target_alias="$3" +output="$4" + +rm -f version.c-tmp $output version.tmp +date=`sed -n -e 's/^.* BFD_VERSION_DATE \(.*\)$/\1/p' $srcdir/../bfd/version.h` +sed -e "s/DATE/$date/" < $srcdir/version.in > version.tmp +echo '#include "gdbsupport/version.h"' >> version.c-tmp +echo 'const char version[] = "'"`sed q version.tmp`"'";' >> version.c-tmp +echo 'const char host_name[] = "'"$host_alias"'";' >> version.c-tmp +echo 'const char target_name[] = "'"$target_alias"'";' >> version.c-tmp +mv version.c-tmp $output +rm -f version.tmp diff --git a/gdbsupport/def-vector.h b/gdbsupport/def-vector.h new file mode 100644 index 0000000..8a4ff6b --- /dev/null +++ b/gdbsupport/def-vector.h @@ -0,0 +1,36 @@ +/* Copyright (C) 2017-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_DEF_VECTOR_H +#define COMMON_DEF_VECTOR_H + +#include <vector> +#include "gdbsupport/default-init-alloc.h" + +namespace gdb { + +/* A vector that uses an allocator that default constructs using + default-initialization rather than value-initialization. The idea + is to use this when you don't want zero-initialization of elements + of vectors of trivial types. E.g., byte buffers. */ + +template<typename T> using def_vector + = std::vector<T, gdb::default_init_allocator<T>>; + +} /* namespace gdb */ + +#endif /* COMMON_DEF_VECTOR_H */ diff --git a/gdbsupport/default-init-alloc.h b/gdbsupport/default-init-alloc.h new file mode 100644 index 0000000..6299aa6 --- /dev/null +++ b/gdbsupport/default-init-alloc.h @@ -0,0 +1,67 @@ +/* Copyright (C) 2017-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_DEFAULT_INIT_ALLOC_H +#define COMMON_DEFAULT_INIT_ALLOC_H + +namespace gdb { + +/* An allocator that default constructs using default-initialization + rather than value-initialization. The idea is to use this when you + don't want to default construct elements of containers of trivial + types using zero-initialization. */ + +/* Mostly as implementation convenience, this is implemented as an + adapter that given an allocator A, overrides 'A::construct()'. 'A' + defaults to std::allocator<T>. */ + +template<typename T, typename A = std::allocator<T>> +class default_init_allocator : public A +{ +public: + /* Pull in A's ctors. */ + using A::A; + + /* Override rebind. */ + template<typename U> + struct rebind + { + /* A couple helpers just to make it a bit more readable. */ + typedef std::allocator_traits<A> traits_; + typedef typename traits_::template rebind_alloc<U> alloc_; + + /* This is what we're after. */ + typedef default_init_allocator<U, alloc_> other; + }; + + /* Make the base allocator's construct method(s) visible. */ + using A::construct; + + /* .. and provide an override/overload for the case of default + construction (i.e., no arguments). This is where we construct + with default-init. */ + template <typename U> + void construct (U *ptr) + noexcept (std::is_nothrow_default_constructible<U>::value) + { + ::new ((void *) ptr) U; /* default-init */ + } +}; + +} /* namespace gdb */ + +#endif /* COMMON_DEFAULT_INIT_ALLOC_H */ diff --git a/gdbsupport/enum-flags.h b/gdbsupport/enum-flags.h new file mode 100644 index 0000000..825ff4f --- /dev/null +++ b/gdbsupport/enum-flags.h @@ -0,0 +1,221 @@ +/* Copyright (C) 2015-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_ENUM_FLAGS_H +#define COMMON_ENUM_FLAGS_H + +/* Type-safe wrapper for enum flags. enum flags are enums where the + values are bits that are meant to be ORed together. + + This allows writing code like the below, while with raw enums this + would fail to compile without casts to enum type at the assignments + to 'f': + + enum some_flag + { + flag_val1 = 1 << 1, + flag_val2 = 1 << 2, + flag_val3 = 1 << 3, + flag_val4 = 1 << 4, + }; + DEF_ENUM_FLAGS_TYPE(enum some_flag, some_flags); + + some_flags f = flag_val1 | flag_val2; + f |= flag_val3; + + It's also possible to assign literal zero to an enum flags variable + (meaning, no flags), dispensing adding an awkward explicit "no + value" value to the enumeration. For example: + + some_flags f = 0; + f |= flag_val3 | flag_val4; + + Note that literal integers other than zero fail to compile: + + some_flags f = 1; // error +*/ + +#ifdef __cplusplus + +/* Traits type used to prevent the global operator overloads from + instantiating for non-flag enums. */ +template<typename T> struct enum_flags_type {}; + +/* Use this to mark an enum as flags enum. It defines FLAGS as + enum_flags wrapper class for ENUM, and enables the global operator + overloads for ENUM. */ +#define DEF_ENUM_FLAGS_TYPE(enum_type, flags_type) \ + typedef enum_flags<enum_type> flags_type; \ + template<> \ + struct enum_flags_type<enum_type> \ + { \ + typedef enum_flags<enum_type> type; \ + } + +/* Until we can rely on std::underlying type being universally + available (C++11), roll our own for enums. */ +template<int size, bool sign> class integer_for_size { typedef void type; }; +template<> struct integer_for_size<1, 0> { typedef uint8_t type; }; +template<> struct integer_for_size<2, 0> { typedef uint16_t type; }; +template<> struct integer_for_size<4, 0> { typedef uint32_t type; }; +template<> struct integer_for_size<8, 0> { typedef uint64_t type; }; +template<> struct integer_for_size<1, 1> { typedef int8_t type; }; +template<> struct integer_for_size<2, 1> { typedef int16_t type; }; +template<> struct integer_for_size<4, 1> { typedef int32_t type; }; +template<> struct integer_for_size<8, 1> { typedef int64_t type; }; + +template<typename T> +struct enum_underlying_type +{ + typedef typename + integer_for_size<sizeof (T), static_cast<bool>(T (-1) < T (0))>::type + type; +}; + +template <typename E> +class enum_flags +{ +public: + typedef E enum_type; + typedef typename enum_underlying_type<enum_type>::type underlying_type; + +private: + /* Private type used to support initializing flag types with zero: + + foo_flags f = 0; + + but not other integers: + + foo_flags f = 1; + + The way this works is that we define an implicit constructor that + takes a pointer to this private type. Since nothing can + instantiate an object of this type, the only possible pointer to + pass to the constructor is the NULL pointer, or, zero. */ + struct zero_type; + + underlying_type + underlying_value () const + { + return m_enum_value; + } + +public: + /* Allow default construction. */ + enum_flags () + : m_enum_value ((enum_type) 0) + {} + + /* If you get an error saying these two overloads are ambiguous, + then you tried to mix values of different enum types. */ + enum_flags (enum_type e) + : m_enum_value (e) + {} + enum_flags (struct enum_flags::zero_type *zero) + : m_enum_value ((enum_type) 0) + {} + + enum_flags &operator&= (enum_type e) + { + m_enum_value = (enum_type) (underlying_value () & e); + return *this; + } + enum_flags &operator|= (enum_type e) + { + m_enum_value = (enum_type) (underlying_value () | e); + return *this; + } + enum_flags &operator^= (enum_type e) + { + m_enum_value = (enum_type) (underlying_value () ^ e); + return *this; + } + + operator enum_type () const + { + return m_enum_value; + } + + enum_flags operator& (enum_type e) const + { + return (enum_type) (underlying_value () & e); + } + enum_flags operator| (enum_type e) const + { + return (enum_type) (underlying_value () | e); + } + enum_flags operator^ (enum_type e) const + { + return (enum_type) (underlying_value () ^ e); + } + enum_flags operator~ () const + { + // We only the underlying type to be unsigned when actually using + // operator~ -- if it were not unsigned, undefined behavior could + // result. However, asserting this in the class itself would + // require too many unnecessary changes to otherwise ok enum + // types. + gdb_static_assert (std::is_unsigned<underlying_type>::value); + return (enum_type) ~underlying_value (); + } + +private: + /* Stored as enum_type because GDB knows to print the bit flags + neatly if the enum values look like bit flags. */ + enum_type m_enum_value; +}; + +/* Global operator overloads. */ + +template <typename enum_type> +typename enum_flags_type<enum_type>::type +operator& (enum_type e1, enum_type e2) +{ + return enum_flags<enum_type> (e1) & e2; +} + +template <typename enum_type> +typename enum_flags_type<enum_type>::type +operator| (enum_type e1, enum_type e2) +{ + return enum_flags<enum_type> (e1) | e2; +} + +template <typename enum_type> +typename enum_flags_type<enum_type>::type +operator^ (enum_type e1, enum_type e2) +{ + return enum_flags<enum_type> (e1) ^ e2; +} + +template <typename enum_type> +typename enum_flags_type<enum_type>::type +operator~ (enum_type e) +{ + return ~enum_flags<enum_type> (e); +} + +#else /* __cplusplus */ + +/* In C, the flags type is just a typedef for the enum type. */ + +#define DEF_ENUM_FLAGS_TYPE(enum_type, flags_type) \ + typedef enum_type flags_type + +#endif /* __cplusplus */ + +#endif /* COMMON_ENUM_FLAGS_H */ diff --git a/gdbsupport/environ.c b/gdbsupport/environ.c new file mode 100644 index 0000000..55d0a74 --- /dev/null +++ b/gdbsupport/environ.c @@ -0,0 +1,183 @@ +/* environ.c -- library for manipulating environments for GNU. + + Copyright (C) 1986-2020 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "common-defs.h" +#include "environ.h" +#include <algorithm> +#include <utility> + +/* See gdbsupport/environ.h. */ + +gdb_environ & +gdb_environ::operator= (gdb_environ &&e) +{ + /* Are we self-moving? */ + if (&e == this) + return *this; + + m_environ_vector = std::move (e.m_environ_vector); + m_user_set_env = std::move (e.m_user_set_env); + m_user_unset_env = std::move (e.m_user_unset_env); + e.m_environ_vector.clear (); + e.m_environ_vector.push_back (NULL); + e.m_user_set_env.clear (); + e.m_user_unset_env.clear (); + return *this; +} + +/* See gdbsupport/environ.h. */ + +gdb_environ gdb_environ::from_host_environ () +{ + extern char **environ; + gdb_environ e; + + if (environ == NULL) + return e; + + for (int i = 0; environ[i] != NULL; ++i) + { + /* Make sure we add the element before the last (NULL). */ + e.m_environ_vector.insert (e.m_environ_vector.end () - 1, + xstrdup (environ[i])); + } + + return e; +} + +/* See gdbsupport/environ.h. */ + +void +gdb_environ::clear () +{ + for (char *v : m_environ_vector) + xfree (v); + m_environ_vector.clear (); + /* Always add the NULL element. */ + m_environ_vector.push_back (NULL); + m_user_set_env.clear (); + m_user_unset_env.clear (); +} + +/* Helper function to check if STRING contains an environment variable + assignment of VAR, i.e., if STRING starts with 'VAR='. Return true + if it contains, false otherwise. */ + +static bool +match_var_in_string (const char *string, const char *var, size_t var_len) +{ + if (strncmp (string, var, var_len) == 0 && string[var_len] == '=') + return true; + + return false; +} + +/* See gdbsupport/environ.h. */ + +const char * +gdb_environ::get (const char *var) const +{ + size_t len = strlen (var); + + for (char *el : m_environ_vector) + if (el != NULL && match_var_in_string (el, var, len)) + return &el[len + 1]; + + return NULL; +} + +/* See gdbsupport/environ.h. */ + +void +gdb_environ::set (const char *var, const char *value) +{ + char *fullvar = concat (var, "=", value, NULL); + + /* We have to unset the variable in the vector if it exists. */ + unset (var, false); + + /* Insert the element before the last one, which is always NULL. */ + m_environ_vector.insert (m_environ_vector.end () - 1, fullvar); + + /* Mark this environment variable as having been set by the user. + This will be useful when we deal with setting environment + variables on the remote target. */ + m_user_set_env.insert (std::string (fullvar)); + + /* If this environment variable is marked as unset by the user, then + remove it from the list, because now the user wants to set + it. */ + m_user_unset_env.erase (std::string (var)); +} + +/* See gdbsupport/environ.h. */ + +void +gdb_environ::unset (const char *var, bool update_unset_list) +{ + size_t len = strlen (var); + std::vector<char *>::iterator it_env; + + /* We iterate until '.end () - 1' because the last element is + always NULL. */ + for (it_env = m_environ_vector.begin (); + it_env != m_environ_vector.end () - 1; + ++it_env) + if (match_var_in_string (*it_env, var, len)) + break; + + if (it_env != m_environ_vector.end () - 1) + { + m_user_set_env.erase (std::string (*it_env)); + xfree (*it_env); + + m_environ_vector.erase (it_env); + } + + if (update_unset_list) + m_user_unset_env.insert (std::string (var)); +} + +/* See gdbsupport/environ.h. */ + +void +gdb_environ::unset (const char *var) +{ + unset (var, true); +} + +/* See gdbsupport/environ.h. */ + +char ** +gdb_environ::envp () const +{ + return const_cast<char **> (&m_environ_vector[0]); +} + +/* See gdbsupport/environ.h. */ + +const std::set<std::string> & +gdb_environ::user_set_env () const +{ + return m_user_set_env; +} + +const std::set<std::string> & +gdb_environ::user_unset_env () const +{ + return m_user_unset_env; +} diff --git a/gdbsupport/environ.h b/gdbsupport/environ.h new file mode 100644 index 0000000..8794a2a --- /dev/null +++ b/gdbsupport/environ.h @@ -0,0 +1,103 @@ +/* Header for environment manipulation library. + Copyright (C) 1989-2020 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_ENVIRON_H +#define COMMON_ENVIRON_H + +#include <vector> +#include <set> + +/* Class that represents the environment variables as seen by the + inferior. */ + +class gdb_environ +{ +public: + /* Regular constructor and destructor. */ + gdb_environ () + { + /* Make sure that the vector contains at least a NULL element. + If/when we add more variables to it, NULL will always be the + last element. */ + m_environ_vector.push_back (NULL); + } + + ~gdb_environ () + { + clear (); + } + + /* Move constructor. */ + gdb_environ (gdb_environ &&e) + : m_environ_vector (std::move (e.m_environ_vector)), + m_user_set_env (std::move (e.m_user_set_env)), + m_user_unset_env (std::move (e.m_user_unset_env)) + { + /* Make sure that the moved-from vector is left at a valid + state (only one NULL element). */ + e.m_environ_vector.clear (); + e.m_environ_vector.push_back (NULL); + e.m_user_set_env.clear (); + e.m_user_unset_env.clear (); + } + + /* Move assignment. */ + gdb_environ &operator= (gdb_environ &&e); + + /* Create a gdb_environ object using the host's environment + variables. */ + static gdb_environ from_host_environ (); + + /* Clear the environment variables stored in the object. */ + void clear (); + + /* Return the value in the environment for the variable VAR. The + returned pointer is only valid as long as the gdb_environ object + is not modified. */ + const char *get (const char *var) const; + + /* Store VAR=VALUE in the environment. */ + void set (const char *var, const char *value); + + /* Unset VAR in environment. */ + void unset (const char *var); + + /* Return the environment vector represented as a 'char **'. */ + char **envp () const; + + /* Return the user-set environment vector. */ + const std::set<std::string> &user_set_env () const; + + /* Return the user-unset environment vector. */ + const std::set<std::string> &user_unset_env () const; + +private: + /* Unset VAR in environment. If UPDATE_UNSET_LIST is true, then + also update M_USER_UNSET_ENV to reflect the unsetting of the + environment variable. */ + void unset (const char *var, bool update_unset_list); + + /* A vector containing the environment variables. */ + std::vector<char *> m_environ_vector; + + /* The environment variables explicitly set by the user. */ + std::set<std::string> m_user_set_env; + + /* The environment variables explicitly unset by the user. */ + std::set<std::string> m_user_unset_env; +}; + +#endif /* COMMON_ENVIRON_H */ diff --git a/gdbsupport/errors.c b/gdbsupport/errors.c new file mode 100644 index 0000000..3fcac79 --- /dev/null +++ b/gdbsupport/errors.c @@ -0,0 +1,69 @@ +/* Error reporting facilities. + + Copyright (C) 1986-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "common-defs.h" +#include "errors.h" + +/* See gdbsupport/errors.h. */ + +void +warning (const char *fmt, ...) +{ + va_list ap; + + va_start (ap, fmt); + vwarning (fmt, ap); + va_end (ap); +} + +/* See gdbsupport/errors.h. */ + +void +error (const char *fmt, ...) +{ + va_list ap; + + va_start (ap, fmt); + verror (fmt, ap); + va_end (ap); +} + +/* See gdbsupport/errors.h. */ + +void +internal_error (const char *file, int line, const char *fmt, ...) +{ + va_list ap; + + va_start (ap, fmt); + internal_verror (file, line, fmt, ap); + va_end (ap); +} + +/* See gdbsupport/errors.h. */ + +void +internal_warning (const char *file, int line, const char *fmt, ...) +{ + va_list ap; + + va_start (ap, fmt); + internal_vwarning (file, line, fmt, ap); + va_end (ap); +} diff --git a/gdbsupport/errors.h b/gdbsupport/errors.h new file mode 100644 index 0000000..da13482 --- /dev/null +++ b/gdbsupport/errors.h @@ -0,0 +1,90 @@ +/* Declarations for error-reporting facilities. + + Copyright (C) 1986-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_ERRORS_H +#define COMMON_ERRORS_H + +/* A problem was detected, but the requested operation can still + proceed. A warning message is constructed using a printf- or + vprintf-style argument list. The function "vwarning" must be + provided by the client. */ + +extern void warning (const char *fmt, ...) + ATTRIBUTE_PRINTF (1, 2); + +extern void vwarning (const char *fmt, va_list args) + ATTRIBUTE_PRINTF (1, 0); + +/* A non-predictable, non-fatal error was detected. The requested + operation cannot proceed. An error message is constructed using + a printf- or vprintf-style argument list. These functions do not + return. The function "verror" must be provided by the client. */ + +extern void error (const char *fmt, ...) + ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (1, 2); + +extern void verror (const char *fmt, va_list args) + ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (1, 0); + +/* An internal error was detected. Internal errors indicate + programming errors such as assertion failures, as opposed to + more general errors beyond the application's control. These + functions do not return. An error message is constructed using + a printf- or vprintf-style argument list. FILE and LINE + indicate the file and line number where the programming error + was detected. The function "internal_verror" must be provided + by the client. */ + +extern void internal_error (const char *file, int line, + const char *fmt, ...) + ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (3, 4); + +extern void internal_verror (const char *file, int line, + const char *fmt, va_list args) + ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (3, 0); + +/* An internal problem was detected, but the requested operation can + still proceed. Internal warnings indicate programming errors as + opposed to more general issues beyond the application's control. + A warning message is constructed using a printf- or vprintf-style + argument list. The function "internal_vwarning" must be provided + by the client. */ + +extern void internal_warning (const char *file, int line, + const char *fmt, ...) + ATTRIBUTE_PRINTF (3, 4); + +extern void internal_vwarning (const char *file, int line, + const char *fmt, va_list args) + ATTRIBUTE_PRINTF (3, 0); + + +/* Like "error", but the error message is constructed by combining + STRING with the system error message for errno. This function does + not return. This function must be provided by the client. */ + +extern void perror_with_name (const char *string) ATTRIBUTE_NORETURN; + +/* Call this function to handle memory allocation failures. This + function does not return. This function must be provided by the + client. */ + +extern void malloc_failure (long size) ATTRIBUTE_NORETURN; + +#endif /* COMMON_ERRORS_H */ diff --git a/gdbsupport/fileio.c b/gdbsupport/fileio.c new file mode 100644 index 0000000..69ed426 --- /dev/null +++ b/gdbsupport/fileio.c @@ -0,0 +1,255 @@ +/* File-I/O functions for GDB, the GNU debugger. + + Copyright (C) 2003-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "common-defs.h" +#include "fileio.h" +#include <sys/stat.h> +#include <fcntl.h> + +/* See fileio.h. */ + +int +host_to_fileio_error (int error) +{ + switch (error) + { + case EPERM: + return FILEIO_EPERM; + case ENOENT: + return FILEIO_ENOENT; + case EINTR: + return FILEIO_EINTR; + case EIO: + return FILEIO_EIO; + case EBADF: + return FILEIO_EBADF; + case EACCES: + return FILEIO_EACCES; + case EFAULT: + return FILEIO_EFAULT; + case EBUSY: + return FILEIO_EBUSY; + case EEXIST: + return FILEIO_EEXIST; + case ENODEV: + return FILEIO_ENODEV; + case ENOTDIR: + return FILEIO_ENOTDIR; + case EISDIR: + return FILEIO_EISDIR; + case EINVAL: + return FILEIO_EINVAL; + case ENFILE: + return FILEIO_ENFILE; + case EMFILE: + return FILEIO_EMFILE; + case EFBIG: + return FILEIO_EFBIG; + case ENOSPC: + return FILEIO_ENOSPC; + case ESPIPE: + return FILEIO_ESPIPE; + case EROFS: + return FILEIO_EROFS; + case ENOSYS: + return FILEIO_ENOSYS; + case ENAMETOOLONG: + return FILEIO_ENAMETOOLONG; + } + return FILEIO_EUNKNOWN; +} + +/* See fileio.h. */ + +int +fileio_to_host_openflags (int fileio_open_flags, int *open_flags_p) +{ + int open_flags = 0; + + if (fileio_open_flags & ~FILEIO_O_SUPPORTED) + return -1; + + if (fileio_open_flags & FILEIO_O_CREAT) + open_flags |= O_CREAT; + if (fileio_open_flags & FILEIO_O_EXCL) + open_flags |= O_EXCL; + if (fileio_open_flags & FILEIO_O_TRUNC) + open_flags |= O_TRUNC; + if (fileio_open_flags & FILEIO_O_APPEND) + open_flags |= O_APPEND; + if (fileio_open_flags & FILEIO_O_RDONLY) + open_flags |= O_RDONLY; + if (fileio_open_flags & FILEIO_O_WRONLY) + open_flags |= O_WRONLY; + if (fileio_open_flags & FILEIO_O_RDWR) + open_flags |= O_RDWR; + /* On systems supporting binary and text mode, always open files + in binary mode. */ +#ifdef O_BINARY + open_flags |= O_BINARY; +#endif + + *open_flags_p = open_flags; + return 0; +} + +/* See fileio.h. */ + +int +fileio_to_host_mode (int fileio_mode, mode_t *mode_p) +{ + mode_t mode = 0; + + if (fileio_mode & ~FILEIO_S_SUPPORTED) + return -1; + + if (fileio_mode & FILEIO_S_IFREG) + mode |= S_IFREG; + if (fileio_mode & FILEIO_S_IFDIR) + mode |= S_IFDIR; + if (fileio_mode & FILEIO_S_IFCHR) + mode |= S_IFCHR; + if (fileio_mode & FILEIO_S_IRUSR) + mode |= S_IRUSR; + if (fileio_mode & FILEIO_S_IWUSR) + mode |= S_IWUSR; + if (fileio_mode & FILEIO_S_IXUSR) + mode |= S_IXUSR; +#ifdef S_IRGRP + if (fileio_mode & FILEIO_S_IRGRP) + mode |= S_IRGRP; +#endif +#ifdef S_IWGRP + if (fileio_mode & FILEIO_S_IWGRP) + mode |= S_IWGRP; +#endif +#ifdef S_IXGRP + if (fileio_mode & FILEIO_S_IXGRP) + mode |= S_IXGRP; +#endif + if (fileio_mode & FILEIO_S_IROTH) + mode |= S_IROTH; +#ifdef S_IWOTH + if (fileio_mode & FILEIO_S_IWOTH) + mode |= S_IWOTH; +#endif +#ifdef S_IXOTH + if (fileio_mode & FILEIO_S_IXOTH) + mode |= S_IXOTH; +#endif + + *mode_p = mode; + return 0; +} + +/* Convert a host-format mode_t into a bitmask of File-I/O flags. */ + +static LONGEST +fileio_mode_pack (mode_t mode) +{ + mode_t tmode = 0; + + if (S_ISREG (mode)) + tmode |= FILEIO_S_IFREG; + if (S_ISDIR (mode)) + tmode |= FILEIO_S_IFDIR; + if (S_ISCHR (mode)) + tmode |= FILEIO_S_IFCHR; + if (mode & S_IRUSR) + tmode |= FILEIO_S_IRUSR; + if (mode & S_IWUSR) + tmode |= FILEIO_S_IWUSR; + if (mode & S_IXUSR) + tmode |= FILEIO_S_IXUSR; +#ifdef S_IRGRP + if (mode & S_IRGRP) + tmode |= FILEIO_S_IRGRP; +#endif +#ifdef S_IWGRP + if (mode & S_IWGRP) + tmode |= FILEIO_S_IWGRP; +#endif +#ifdef S_IXGRP + if (mode & S_IXGRP) + tmode |= FILEIO_S_IXGRP; +#endif + if (mode & S_IROTH) + tmode |= FILEIO_S_IROTH; +#ifdef S_IWOTH + if (mode & S_IWOTH) + tmode |= FILEIO_S_IWOTH; +#endif +#ifdef S_IXOTH + if (mode & S_IXOTH) + tmode |= FILEIO_S_IXOTH; +#endif + return tmode; +} + +/* Pack a host-format mode_t into an fio_mode_t. */ + +static void +host_to_fileio_mode (mode_t num, fio_mode_t fnum) +{ + host_to_bigendian (fileio_mode_pack (num), (char *) fnum, 4); +} + +/* Pack a host-format integer into an fio_ulong_t. */ + +static void +host_to_fileio_ulong (LONGEST num, fio_ulong_t fnum) +{ + host_to_bigendian (num, (char *) fnum, 8); +} + +/* See fileio.h. */ + +void +host_to_fileio_stat (struct stat *st, struct fio_stat *fst) +{ + LONGEST blksize; + + host_to_fileio_uint ((long) st->st_dev, fst->fst_dev); + host_to_fileio_uint ((long) st->st_ino, fst->fst_ino); + host_to_fileio_mode (st->st_mode, fst->fst_mode); + host_to_fileio_uint ((long) st->st_nlink, fst->fst_nlink); + host_to_fileio_uint ((long) st->st_uid, fst->fst_uid); + host_to_fileio_uint ((long) st->st_gid, fst->fst_gid); + host_to_fileio_uint ((long) st->st_rdev, fst->fst_rdev); + host_to_fileio_ulong ((LONGEST) st->st_size, fst->fst_size); +#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE + blksize = st->st_blksize; +#else + blksize = 512; +#endif + host_to_fileio_ulong (blksize, fst->fst_blksize); +#if HAVE_STRUCT_STAT_ST_BLOCKS + host_to_fileio_ulong ((LONGEST) st->st_blocks, fst->fst_blocks); +#else + /* FIXME: This is correct for DJGPP, but other systems that don't + have st_blocks, if any, might prefer 512 instead of st_blksize. + (eliz, 30-12-2003) */ + host_to_fileio_ulong (((LONGEST) st->st_size + blksize - 1) + / blksize, + fst->fst_blocks); +#endif + host_to_fileio_time (st->st_atime, fst->fst_atime); + host_to_fileio_time (st->st_mtime, fst->fst_mtime); + host_to_fileio_time (st->st_ctime, fst->fst_ctime); +} diff --git a/gdbsupport/fileio.h b/gdbsupport/fileio.h new file mode 100644 index 0000000..9d33e46 --- /dev/null +++ b/gdbsupport/fileio.h @@ -0,0 +1,73 @@ +/* File-I/O functions for GDB, the GNU debugger. + + Copyright (C) 2003-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_FILEIO_H +#define COMMON_FILEIO_H + +#include "gdb/fileio.h" +#include <sys/stat.h> + +/* Convert a host-format errno value to a File-I/O error number. */ + +extern int host_to_fileio_error (int error); + +/* Convert File-I/O open flags FFLAGS to host format, storing + the result in *FLAGS. Return 0 on success, -1 on error. */ + +extern int fileio_to_host_openflags (int fflags, int *flags); + +/* Convert File-I/O mode FMODE to host format, storing + the result in *MODE. Return 0 on success, -1 on error. */ + +extern int fileio_to_host_mode (int fmode, mode_t *mode); + +/* Pack a host-format integer into a byte buffer in big-endian + format. BYTES specifies the size of the integer to pack in + bytes. */ + +static inline void +host_to_bigendian (LONGEST num, char *buf, int bytes) +{ + int i; + + for (i = 0; i < bytes; ++i) + buf[i] = (num >> (8 * (bytes - i - 1))) & 0xff; +} + +/* Pack a host-format integer into an fio_uint_t. */ + +static inline void +host_to_fileio_uint (long num, fio_uint_t fnum) +{ + host_to_bigendian ((LONGEST) num, (char *) fnum, 4); +} + +/* Pack a host-format time_t into an fio_time_t. */ + +static inline void +host_to_fileio_time (time_t num, fio_time_t fnum) +{ + host_to_bigendian ((LONGEST) num, (char *) fnum, 4); +} + +/* Pack a host-format struct stat into a struct fio_stat. */ + +extern void host_to_fileio_stat (struct stat *st, struct fio_stat *fst); + +#endif /* COMMON_FILEIO_H */ diff --git a/gdbsupport/filestuff.c b/gdbsupport/filestuff.c new file mode 100644 index 0000000..179c425 --- /dev/null +++ b/gdbsupport/filestuff.c @@ -0,0 +1,503 @@ +/* Low-level file-handling. + Copyright (C) 2012-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "common-defs.h" +#include "filestuff.h" +#include "gdb_vecs.h" +#include <fcntl.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <algorithm> + +#ifdef USE_WIN32API +#include <winsock2.h> +#include <windows.h> +#define HAVE_SOCKETS 1 +#elif defined HAVE_SYS_SOCKET_H +#include <sys/socket.h> +/* Define HAVE_F_GETFD if we plan to use F_GETFD. */ +#define HAVE_F_GETFD F_GETFD +#define HAVE_SOCKETS 1 +#endif + +#ifdef HAVE_KINFO_GETFILE +#include <sys/user.h> +#include <libutil.h> +#endif + +#ifdef HAVE_SYS_RESOURCE_H +#include <sys/resource.h> +#endif /* HAVE_SYS_RESOURCE_H */ + +#ifndef O_CLOEXEC +#define O_CLOEXEC 0 +#endif + +#ifndef O_NOINHERIT +#define O_NOINHERIT 0 +#endif + +#ifndef SOCK_CLOEXEC +#define SOCK_CLOEXEC 0 +#endif + + + +#ifndef HAVE_FDWALK + +#include <dirent.h> + +/* Replacement for fdwalk, if the system doesn't define it. Walks all + open file descriptors (though this implementation may walk closed + ones as well, depending on the host platform's capabilities) and + call FUNC with ARG. If FUNC returns non-zero, stops immediately + and returns the same value. Otherwise, returns zero when + finished. */ + +static int +fdwalk (int (*func) (void *, int), void *arg) +{ + /* Checking __linux__ isn't great but it isn't clear what would be + better. There doesn't seem to be a good way to check for this in + configure. */ +#ifdef __linux__ + DIR *dir; + + dir = opendir ("/proc/self/fd"); + if (dir != NULL) + { + struct dirent *entry; + int result = 0; + + for (entry = readdir (dir); entry != NULL; entry = readdir (dir)) + { + long fd; + char *tail; + + errno = 0; + fd = strtol (entry->d_name, &tail, 10); + if (*tail != '\0' || errno != 0) + continue; + if ((int) fd != fd) + { + /* What can we do here really? */ + continue; + } + + if (fd == dirfd (dir)) + continue; + + result = func (arg, fd); + if (result != 0) + break; + } + + closedir (dir); + return result; + } + /* We may fall through to the next case. */ +#endif +#ifdef HAVE_KINFO_GETFILE + int nfd; + gdb::unique_xmalloc_ptr<struct kinfo_file[]> fdtbl + (kinfo_getfile (getpid (), &nfd)); + if (fdtbl != NULL) + { + for (int i = 0; i < nfd; i++) + { + if (fdtbl[i].kf_fd >= 0) + { + int result = func (arg, fdtbl[i].kf_fd); + if (result != 0) + return result; + } + } + return 0; + } + /* We may fall through to the next case. */ +#endif + + { + int max, fd; + +#if defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE) + struct rlimit rlim; + + if (getrlimit (RLIMIT_NOFILE, &rlim) == 0 && rlim.rlim_max != RLIM_INFINITY) + max = rlim.rlim_max; + else +#endif + { +#ifdef _SC_OPEN_MAX + max = sysconf (_SC_OPEN_MAX); +#else + /* Whoops. */ + return 0; +#endif /* _SC_OPEN_MAX */ + } + + for (fd = 0; fd < max; ++fd) + { + struct stat sb; + int result; + + /* Only call FUNC for open fds. */ + if (fstat (fd, &sb) == -1) + continue; + + result = func (arg, fd); + if (result != 0) + return result; + } + + return 0; + } +} + +#endif /* HAVE_FDWALK */ + + + +/* A vector holding all the fds open when notice_open_fds was called. We + don't use a hashtab because we don't expect there to be many open fds. */ + +static std::vector<int> open_fds; + +/* An fdwalk callback function used by notice_open_fds. It puts the + given file descriptor into the vec. */ + +static int +do_mark_open_fd (void *ignore, int fd) +{ + open_fds.push_back (fd); + return 0; +} + +/* See filestuff.h. */ + +void +notice_open_fds (void) +{ + fdwalk (do_mark_open_fd, NULL); +} + +/* See filestuff.h. */ + +void +mark_fd_no_cloexec (int fd) +{ + do_mark_open_fd (NULL, fd); +} + +/* See filestuff.h. */ + +void +unmark_fd_no_cloexec (int fd) +{ + auto it = std::remove (open_fds.begin (), open_fds.end (), fd); + + if (it != open_fds.end ()) + open_fds.erase (it); + else + gdb_assert_not_reached (_("fd not found in open_fds")); +} + +/* Helper function for close_most_fds that closes the file descriptor + if appropriate. */ + +static int +do_close (void *ignore, int fd) +{ + for (int val : open_fds) + { + if (fd == val) + { + /* Keep this one open. */ + return 0; + } + } + + close (fd); + return 0; +} + +/* See filestuff.h. */ + +void +close_most_fds (void) +{ + fdwalk (do_close, NULL); +} + + + +/* This is a tri-state flag. When zero it means we haven't yet tried + O_CLOEXEC. When positive it means that O_CLOEXEC works on this + host. When negative, it means that O_CLOEXEC doesn't work. We + track this state because, while gdb might have been compiled + against a libc that supplies O_CLOEXEC, there is no guarantee that + the kernel supports it. */ + +static int trust_o_cloexec; + +/* Mark FD as close-on-exec, ignoring errors. Update + TRUST_O_CLOEXEC. */ + +static void +mark_cloexec (int fd) +{ +#ifdef HAVE_F_GETFD + int old = fcntl (fd, F_GETFD, 0); + + if (old != -1) + { + fcntl (fd, F_SETFD, old | FD_CLOEXEC); + + if (trust_o_cloexec == 0) + { + if ((old & FD_CLOEXEC) != 0) + trust_o_cloexec = 1; + else + trust_o_cloexec = -1; + } + } +#endif /* HAVE_F_GETFD */ +} + +/* Depending on TRUST_O_CLOEXEC, mark FD as close-on-exec. */ + +static void +maybe_mark_cloexec (int fd) +{ + if (trust_o_cloexec <= 0) + mark_cloexec (fd); +} + +#ifdef HAVE_SOCKETS + +/* Like maybe_mark_cloexec, but for callers that use SOCK_CLOEXEC. */ + +static void +socket_mark_cloexec (int fd) +{ + if (SOCK_CLOEXEC == 0 || trust_o_cloexec <= 0) + mark_cloexec (fd); +} + +#endif + + + +/* See filestuff.h. */ + +int +gdb_open_cloexec (const char *filename, int flags, unsigned long mode) +{ + int fd = open (filename, flags | O_CLOEXEC, mode); + + if (fd >= 0) + maybe_mark_cloexec (fd); + + return fd; +} + +/* See filestuff.h. */ + +gdb_file_up +gdb_fopen_cloexec (const char *filename, const char *opentype) +{ + FILE *result; + /* Probe for "e" support once. But, if we can tell the operating + system doesn't know about close on exec mode "e" without probing, + skip it. E.g., the Windows runtime issues an "Invalid parameter + passed to C runtime function" OutputDebugString warning for + unknown modes. Assume that if O_CLOEXEC is zero, then "e" isn't + supported. On MinGW, O_CLOEXEC is an alias of O_NOINHERIT, and + "e" isn't supported. */ + static int fopen_e_ever_failed_einval = + O_CLOEXEC == 0 || O_CLOEXEC == O_NOINHERIT; + + if (!fopen_e_ever_failed_einval) + { + char *copy; + + copy = (char *) alloca (strlen (opentype) + 2); + strcpy (copy, opentype); + /* This is a glibc extension but we try it unconditionally on + this path. */ + strcat (copy, "e"); + result = fopen (filename, copy); + + if (result == NULL && errno == EINVAL) + { + result = fopen (filename, opentype); + if (result != NULL) + fopen_e_ever_failed_einval = 1; + } + } + else + result = fopen (filename, opentype); + + if (result != NULL) + maybe_mark_cloexec (fileno (result)); + + return gdb_file_up (result); +} + +#ifdef HAVE_SOCKETS +/* See filestuff.h. */ + +int +gdb_socketpair_cloexec (int domain, int style, int protocol, + int filedes[2]) +{ +#ifdef HAVE_SOCKETPAIR + int result = socketpair (domain, style | SOCK_CLOEXEC, protocol, filedes); + + if (result != -1) + { + socket_mark_cloexec (filedes[0]); + socket_mark_cloexec (filedes[1]); + } + + return result; +#else + gdb_assert_not_reached (_("socketpair not available on this host")); +#endif +} + +/* See filestuff.h. */ + +int +gdb_socket_cloexec (int domain, int style, int protocol) +{ + int result = socket (domain, style | SOCK_CLOEXEC, protocol); + + if (result != -1) + socket_mark_cloexec (result); + + return result; +} +#endif + +/* See filestuff.h. */ + +int +gdb_pipe_cloexec (int filedes[2]) +{ + int result; + +#ifdef HAVE_PIPE2 + result = pipe2 (filedes, O_CLOEXEC); + if (result != -1) + { + maybe_mark_cloexec (filedes[0]); + maybe_mark_cloexec (filedes[1]); + } +#else +#ifdef HAVE_PIPE + result = pipe (filedes); + if (result != -1) + { + mark_cloexec (filedes[0]); + mark_cloexec (filedes[1]); + } +#else /* HAVE_PIPE */ + gdb_assert_not_reached (_("pipe not available on this host")); +#endif /* HAVE_PIPE */ +#endif /* HAVE_PIPE2 */ + + return result; +} + +/* See gdbsupport/filestuff.h. */ + +bool +is_regular_file (const char *name, int *errno_ptr) +{ + struct stat st; + const int status = stat (name, &st); + + /* Stat should never fail except when the file does not exist. + If stat fails, analyze the source of error and return true + unless the file does not exist, to avoid returning false results + on obscure systems where stat does not work as expected. */ + + if (status != 0) + { + if (errno != ENOENT) + return true; + *errno_ptr = ENOENT; + return false; + } + + if (S_ISREG (st.st_mode)) + return true; + + if (S_ISDIR (st.st_mode)) + *errno_ptr = EISDIR; + else + *errno_ptr = EINVAL; + return false; +} + +/* See gdbsupport/filestuff.h. */ + +bool +mkdir_recursive (const char *dir) +{ + auto holder = make_unique_xstrdup (dir); + char * const start = holder.get (); + char *component_start = start; + char *component_end = start; + + while (1) + { + /* Find the beginning of the next component. */ + while (*component_start == '/') + component_start++; + + /* Are we done? */ + if (*component_start == '\0') + return true; + + /* Find the slash or null-terminator after this component. */ + component_end = component_start; + while (*component_end != '/' && *component_end != '\0') + component_end++; + + /* Temporarily replace the slash with a null terminator, so we can create + the directory up to this component. */ + char saved_char = *component_end; + *component_end = '\0'; + + /* If we get EEXIST and the existing path is a directory, then we're + happy. If it exists, but it's a regular file and this is not the last + component, we'll fail at the next component. If this is the last + component, the caller will fail with ENOTDIR when trying to + open/create a file under that path. */ + if (mkdir (start, 0700) != 0) + if (errno != EEXIST) + return false; + + /* Restore the overwritten char. */ + *component_end = saved_char; + component_start = component_end; + } +} diff --git a/gdbsupport/filestuff.h b/gdbsupport/filestuff.h new file mode 100644 index 0000000..e36936a --- /dev/null +++ b/gdbsupport/filestuff.h @@ -0,0 +1,142 @@ +/* Low-level file-handling. + Copyright (C) 2012-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_FILESTUFF_H +#define COMMON_FILESTUFF_H + +#include <dirent.h> +#include <fcntl.h> + +/* Note all the file descriptors which are open when this is called. + These file descriptors will not be closed by close_most_fds. */ + +extern void notice_open_fds (void); + +/* Mark a file descriptor as inheritable across an exec. */ + +extern void mark_fd_no_cloexec (int fd); + +/* Mark a file descriptor as no longer being inheritable across an + exec. This is only meaningful when FD was previously passed to + mark_fd_no_cloexec. */ + +extern void unmark_fd_no_cloexec (int fd); + +/* Close all open file descriptors other than those marked by + 'notice_open_fds', and stdin, stdout, and stderr. Errors that + occur while closing are ignored. */ + +extern void close_most_fds (void); + +/* Like 'open', but ensures that the returned file descriptor has the + close-on-exec flag set. */ + +extern int gdb_open_cloexec (const char *filename, int flags, + /* mode_t */ unsigned long mode); + +/* Like mkstemp, but ensures that the file descriptor is + close-on-exec. */ + +static inline int +gdb_mkostemp_cloexec (char *name_template, int flags = 0) +{ + /* gnulib provides a mkostemp replacement if needed. */ + return mkostemp (name_template, flags | O_CLOEXEC); +} + +/* Convenience wrapper for the above, which takes the filename as an + std::string. */ + +static inline int +gdb_open_cloexec (const std::string &filename, int flags, + /* mode_t */ unsigned long mode) +{ + return gdb_open_cloexec (filename.c_str (), flags, mode); +} + +struct gdb_file_deleter +{ + void operator() (FILE *file) const + { + fclose (file); + } +}; + +/* A unique pointer to a FILE. */ + +typedef std::unique_ptr<FILE, gdb_file_deleter> gdb_file_up; + +/* Like 'fopen', but ensures that the returned file descriptor has the + close-on-exec flag set. */ + +extern gdb_file_up gdb_fopen_cloexec (const char *filename, + const char *opentype); + +/* Convenience wrapper for the above, which takes the filename as an + std::string. */ + +static inline gdb_file_up +gdb_fopen_cloexec (const std::string &filename, const char *opentype) +{ + return gdb_fopen_cloexec (filename.c_str (), opentype); +} + +/* Like 'socketpair', but ensures that the returned file descriptors + have the close-on-exec flag set. */ + +extern int gdb_socketpair_cloexec (int domain, int style, int protocol, + int filedes[2]); + +/* Like 'socket', but ensures that the returned file descriptor has + the close-on-exec flag set. */ + +extern int gdb_socket_cloexec (int domain, int style, int protocol); + +/* Like 'pipe', but ensures that the returned file descriptors have + the close-on-exec flag set. */ + +extern int gdb_pipe_cloexec (int filedes[2]); + +struct gdb_dir_deleter +{ + void operator() (DIR *dir) const + { + closedir (dir); + } +}; + +/* A unique pointer to a DIR. */ + +typedef std::unique_ptr<DIR, gdb_dir_deleter> gdb_dir_up; + +/* Return true if the file NAME exists and is a regular file. + If the result is false then *ERRNO_PTR is set to a useful value assuming + we're expecting a regular file. */ +extern bool is_regular_file (const char *name, int *errno_ptr); + + +/* A cheap (as in low-quality) recursive mkdir. Try to create all the + parents directories up to DIR and DIR itself. Stop if we hit an + error along the way. There is no attempt to remove created + directories in case of failure. + + Returns false on failure and sets errno. */ + +extern bool mkdir_recursive (const char *dir); + +#endif /* COMMON_FILESTUFF_H */ diff --git a/gdbsupport/filtered-iterator.h b/gdbsupport/filtered-iterator.h new file mode 100644 index 0000000..c3aeb44 --- /dev/null +++ b/gdbsupport/filtered-iterator.h @@ -0,0 +1,87 @@ +/* A forward filtered iterator for GDB, the GNU debugger. + Copyright (C) 2018-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_FILTERED_ITERATOR_H +#define COMMON_FILTERED_ITERATOR_H + +/* A filtered iterator. This wraps BaseIterator and automatically + skips elements that FilterFunc filters out. Requires that + default-constructing a BaseIterator creates a valid one-past-end + iterator. */ + +template<typename BaseIterator, typename FilterFunc> +class filtered_iterator +{ +public: + typedef filtered_iterator self_type; + typedef typename BaseIterator::value_type value_type; + typedef typename BaseIterator::reference reference; + typedef typename BaseIterator::pointer pointer; + typedef typename BaseIterator::iterator_category iterator_category; + typedef typename BaseIterator::difference_type difference_type; + + /* Construct by forwarding all arguments to the underlying + iterator. */ + template<typename... Args> + explicit filtered_iterator (Args &&...args) + : m_it (std::forward<Args> (args)...) + { skip_filtered (); } + + /* Create a one-past-end iterator. */ + filtered_iterator () = default; + + /* Need these as the variadic constructor would be a better match + otherwise. */ + filtered_iterator (filtered_iterator &) = default; + filtered_iterator (const filtered_iterator &) = default; + filtered_iterator (filtered_iterator &&) = default; + filtered_iterator (const filtered_iterator &&other) + : filtered_iterator (static_cast<const filtered_iterator &> (other)) + {} + + value_type operator* () const { return *m_it; } + + self_type &operator++ () + { + ++m_it; + skip_filtered (); + return *this; + } + + bool operator== (const self_type &other) const + { return m_it == other.m_it; } + + bool operator!= (const self_type &other) const + { return m_it != other.m_it; } + +private: + + void skip_filtered () + { + for (; m_it != m_end; ++m_it) + if (m_filter (*m_it)) + break; + } + +private: + FilterFunc m_filter {}; + BaseIterator m_it {}; + BaseIterator m_end {}; +}; + +#endif /* COMMON_FILTERED_ITERATOR_H */ diff --git a/gdbsupport/format.c b/gdbsupport/format.c new file mode 100644 index 0000000..b05ccf6 --- /dev/null +++ b/gdbsupport/format.c @@ -0,0 +1,412 @@ +/* Parse a printf-style format string. + + Copyright (C) 1986-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "common-defs.h" +#include "format.h" + +format_pieces::format_pieces (const char **arg, bool gdb_extensions) +{ + const char *s; + const char *string; + const char *prev_start; + const char *percent_loc; + char *sub_start, *current_substring; + enum argclass this_argclass; + + s = *arg; + + if (gdb_extensions) + { + string = *arg; + *arg += strlen (*arg); + } + else + { + /* Parse the format-control string and copy it into the string STRING, + processing some kinds of escape sequence. */ + + char *f = (char *) alloca (strlen (s) + 1); + string = f; + + while ((gdb_extensions || *s != '"') && *s != '\0') + { + int c = *s++; + switch (c) + { + case '\0': + continue; + + case '\\': + switch (c = *s++) + { + case '\\': + *f++ = '\\'; + break; + case 'a': + *f++ = '\a'; + break; + case 'b': + *f++ = '\b'; + break; + case 'e': + *f++ = '\e'; + break; + case 'f': + *f++ = '\f'; + break; + case 'n': + *f++ = '\n'; + break; + case 'r': + *f++ = '\r'; + break; + case 't': + *f++ = '\t'; + break; + case 'v': + *f++ = '\v'; + break; + case '"': + *f++ = '"'; + break; + default: + /* ??? TODO: handle other escape sequences. */ + error (_("Unrecognized escape character \\%c in format string."), + c); + } + break; + + default: + *f++ = c; + } + } + + /* Terminate our escape-processed copy. */ + *f++ = '\0'; + + /* Whether the format string ended with double-quote or zero, we're + done with it; it's up to callers to complain about syntax. */ + *arg = s; + } + + /* Need extra space for the '\0's. Doubling the size is sufficient. */ + + current_substring = (char *) xmalloc (strlen (string) * 2 + 1000); + m_storage.reset (current_substring); + + /* Now scan the string for %-specs and see what kinds of args they want. + argclass classifies the %-specs so we can give printf-type functions + something of the right size. */ + + const char *f = string; + prev_start = string; + while (*f) + if (*f++ == '%') + { + int seen_hash = 0, seen_zero = 0, lcount = 0, seen_prec = 0; + int seen_space = 0, seen_plus = 0; + int seen_big_l = 0, seen_h = 0, seen_big_h = 0; + int seen_big_d = 0, seen_double_big_d = 0; + int seen_size_t = 0; + int bad = 0; + int n_int_args = 0; + bool seen_i64 = false; + + /* Skip over "%%", it will become part of a literal piece. */ + if (*f == '%') + { + f++; + continue; + } + + sub_start = current_substring; + + strncpy (current_substring, prev_start, f - 1 - prev_start); + current_substring += f - 1 - prev_start; + *current_substring++ = '\0'; + + if (*sub_start != '\0') + m_pieces.emplace_back (sub_start, literal_piece, 0); + + percent_loc = f - 1; + + /* Check the validity of the format specifier, and work + out what argument it expects. We only accept C89 + format strings, with the exception of long long (which + we autoconf for). */ + + /* The first part of a format specifier is a set of flag + characters. */ + while (*f != '\0' && strchr ("0-+ #", *f)) + { + if (*f == '#') + seen_hash = 1; + else if (*f == '0') + seen_zero = 1; + else if (*f == ' ') + seen_space = 1; + else if (*f == '+') + seen_plus = 1; + f++; + } + + /* The next part of a format specifier is a width. */ + if (gdb_extensions && *f == '*') + { + ++f; + ++n_int_args; + } + else + { + while (*f != '\0' && strchr ("0123456789", *f)) + f++; + } + + /* The next part of a format specifier is a precision. */ + if (*f == '.') + { + seen_prec = 1; + f++; + if (gdb_extensions && *f == '*') + { + ++f; + ++n_int_args; + } + else + { + while (*f != '\0' && strchr ("0123456789", *f)) + f++; + } + } + + /* The next part of a format specifier is a length modifier. */ + switch (*f) + { + case 'h': + seen_h = 1; + f++; + break; + case 'l': + f++; + lcount++; + if (*f == 'l') + { + f++; + lcount++; + } + break; + case 'L': + seen_big_l = 1; + f++; + break; + case 'H': + /* Decimal32 modifier. */ + seen_big_h = 1; + f++; + break; + case 'D': + /* Decimal64 and Decimal128 modifiers. */ + f++; + + /* Check for a Decimal128. */ + if (*f == 'D') + { + f++; + seen_double_big_d = 1; + } + else + seen_big_d = 1; + break; + case 'z': + /* For size_t or ssize_t. */ + seen_size_t = 1; + f++; + break; + case 'I': + /* Support the Windows '%I64' extension, because an + earlier call to format_pieces might have converted %lld + to %I64d. */ + if (f[1] == '6' && f[2] == '4') + { + f += 3; + lcount = 2; + seen_i64 = true; + } + break; + } + + switch (*f) + { + case 'u': + if (seen_hash) + bad = 1; + /* FALLTHROUGH */ + + case 'o': + case 'x': + case 'X': + if (seen_space || seen_plus) + bad = 1; + /* FALLTHROUGH */ + + case 'd': + case 'i': + if (seen_size_t) + this_argclass = size_t_arg; + else if (lcount == 0) + this_argclass = int_arg; + else if (lcount == 1) + this_argclass = long_arg; + else + this_argclass = long_long_arg; + + if (seen_big_l) + bad = 1; + break; + + case 'c': + this_argclass = lcount == 0 ? int_arg : wide_char_arg; + if (lcount > 1 || seen_h || seen_big_l) + bad = 1; + if (seen_prec || seen_zero || seen_space || seen_plus) + bad = 1; + break; + + case 'p': + this_argclass = ptr_arg; + if (lcount || seen_h || seen_big_l) + bad = 1; + if (seen_prec) + bad = 1; + if (seen_hash || seen_zero || seen_space || seen_plus) + bad = 1; + + if (gdb_extensions) + { + switch (f[1]) + { + case 's': + case 'F': + case '[': + case ']': + f++; + break; + } + } + + break; + + case 's': + this_argclass = lcount == 0 ? string_arg : wide_string_arg; + if (lcount > 1 || seen_h || seen_big_l) + bad = 1; + if (seen_zero || seen_space || seen_plus) + bad = 1; + break; + + case 'e': + case 'f': + case 'g': + case 'E': + case 'G': + if (seen_double_big_d) + this_argclass = dec128float_arg; + else if (seen_big_d) + this_argclass = dec64float_arg; + else if (seen_big_h) + this_argclass = dec32float_arg; + else if (seen_big_l) + this_argclass = long_double_arg; + else + this_argclass = double_arg; + + if (lcount || seen_h) + bad = 1; + break; + + case '*': + error (_("`*' not supported for precision or width in printf")); + + case 'n': + error (_("Format specifier `n' not supported in printf")); + + case '\0': + error (_("Incomplete format specifier at end of format string")); + + default: + error (_("Unrecognized format specifier '%c' in printf"), *f); + } + + if (bad) + error (_("Inappropriate modifiers to " + "format specifier '%c' in printf"), + *f); + + f++; + + sub_start = current_substring; + + if (lcount > 1 && !seen_i64 && USE_PRINTF_I64) + { + /* Windows' printf does support long long, but not the usual way. + Convert %lld to %I64d. */ + int length_before_ll = f - percent_loc - 1 - lcount; + + strncpy (current_substring, percent_loc, length_before_ll); + strcpy (current_substring + length_before_ll, "I64"); + current_substring[length_before_ll + 3] = + percent_loc[length_before_ll + lcount]; + current_substring += length_before_ll + 4; + } + else if (this_argclass == wide_string_arg + || this_argclass == wide_char_arg) + { + /* Convert %ls or %lc to %s. */ + int length_before_ls = f - percent_loc - 2; + + strncpy (current_substring, percent_loc, length_before_ls); + strcpy (current_substring + length_before_ls, "s"); + current_substring += length_before_ls + 2; + } + else + { + strncpy (current_substring, percent_loc, f - percent_loc); + current_substring += f - percent_loc; + } + + *current_substring++ = '\0'; + + prev_start = f; + + m_pieces.emplace_back (sub_start, this_argclass, n_int_args); + } + + /* Record the remainder of the string. */ + + if (f > prev_start) + { + sub_start = current_substring; + + strncpy (current_substring, prev_start, f - prev_start); + current_substring += f - prev_start; + *current_substring++ = '\0'; + + m_pieces.emplace_back (sub_start, literal_piece, 0); + } +} diff --git a/gdbsupport/format.h b/gdbsupport/format.h new file mode 100644 index 0000000..80f012a --- /dev/null +++ b/gdbsupport/format.h @@ -0,0 +1,101 @@ +/* Parse a printf-style format string. + + Copyright (C) 1986-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_FORMAT_H +#define COMMON_FORMAT_H + +#include "gdbsupport/gdb_string_view.h" + +#if defined(__MINGW32__) && !defined(PRINTF_HAS_LONG_LONG) +# define USE_PRINTF_I64 1 +# define PRINTF_HAS_LONG_LONG +#else +# define USE_PRINTF_I64 0 +#endif + +/* The argclass represents the general type of data that goes with a + format directive; int_arg for %d, long_arg for %l, and so forth. + Note that these primarily distinguish types by size and need for + special handling, so for instance %u and %x are (at present) also + classed as int_arg. */ + +enum argclass + { + literal_piece, + int_arg, long_arg, long_long_arg, size_t_arg, ptr_arg, + string_arg, wide_string_arg, wide_char_arg, + double_arg, long_double_arg, + dec32float_arg, dec64float_arg, dec128float_arg + }; + +/* A format piece is a section of the format string that may include a + single print directive somewhere in it, and the associated class + for the argument. */ + +struct format_piece +{ + format_piece (const char *str, enum argclass argc, int n) + : string (str), + argclass (argc), + n_int_args (n) + { + } + + bool operator== (const format_piece &other) const + { + return (this->argclass == other.argclass + && gdb::string_view (this->string) == other.string); + } + + const char *string; + enum argclass argclass; + /* Count the number of preceding 'int' arguments that must be passed + along. This is used for a width or precision of '*'. Note that + this feature is only available in "gdb_extensions" mode. */ + int n_int_args; +}; + +class format_pieces +{ +public: + + format_pieces (const char **arg, bool gdb_extensions = false); + ~format_pieces () = default; + + DISABLE_COPY_AND_ASSIGN (format_pieces); + + typedef std::vector<format_piece>::iterator iterator; + + iterator begin () + { + return m_pieces.begin (); + } + + iterator end () + { + return m_pieces.end (); + } + +private: + + std::vector<format_piece> m_pieces; + gdb::unique_xmalloc_ptr<char> m_storage; +}; + +#endif /* COMMON_FORMAT_H */ diff --git a/gdbsupport/forward-scope-exit.h b/gdbsupport/forward-scope-exit.h new file mode 100644 index 0000000..5ecea380 --- /dev/null +++ b/gdbsupport/forward-scope-exit.h @@ -0,0 +1,123 @@ +/* Copyright (C) 2019-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_FORWARD_SCOPE_EXIT_H +#define COMMON_FORWARD_SCOPE_EXIT_H + +#include "gdbsupport/scope-exit.h" +#include <functional> + +/* A forward_scope_exit is like scope_exit, but instead of giving it a + callable, you instead specialize it for a given cleanup function, + and the generated class automatically has a constructor with the + same interface as the cleanup function. forward_scope_exit + captures the arguments passed to the ctor, and in turn passes those + as arguments to the wrapped cleanup function, when it is called at + scope exit time, from within the forward_scope_exit dtor. The + forward_scope_exit class can take any number of arguments, and is + cancelable if needed. + + This allows usage like this: + + void + delete_longjmp_breakpoint (int arg) + { + // Blah, blah, blah... + } + + using longjmp_breakpoint_cleanup + = FORWARD_SCOPE_EXIT (delete_longjmp_breakpoint); + + This above created a new cleanup class `longjmp_breakpoint_cleanup` + than can then be used like this: + + longjmp_breakpoint_cleanup obj (thread); + + // Blah, blah, blah... + + obj.release (); // Optional cancel if needed. + + forward_scope_exit is also handy when you would need to wrap a + scope_exit in a gdb::optional: + + gdb::optional<longjmp_breakpoint_cleanup> cleanup; + if (some condition) + cleanup.emplace (thread); + ... + if (cleanup) + cleanup->release (); + + since with scope exit, you would have to know the scope_exit's + callable template type when you create the gdb::optional: + + gdb:optional<scope_exit<what goes here?>> + + The "forward" naming fits both purposes shown above -- the class + "forwards" ctor arguments to the wrapped cleanup function at scope + exit time, and can also be used to "forward declare" + scope_exit-like objects. */ + +namespace detail +{ + +/* Function and Signature are passed in the same type, in order to + extract Function's arguments' types in the specialization below. + Those are used to generate the constructor. */ + +template<typename Function, Function *function, typename Signature> +struct forward_scope_exit; + +template<typename Function, Function *function, + typename Res, typename... Args> +class forward_scope_exit<Function, function, Res (Args...)> + : public scope_exit_base<forward_scope_exit<Function, + function, + Res (Args...)>> +{ + /* For access to on_exit(). */ + friend scope_exit_base<forward_scope_exit<Function, + function, + Res (Args...)>>; + +public: + explicit forward_scope_exit (Args ...args) + : m_bind_function (function, args...) + { + /* Nothing. */ + } + +private: + void on_exit () + { + m_bind_function (); + } + + /* The function and the arguments passed to the ctor, all packed in + a std::bind. */ + decltype (std::bind (function, std::declval<Args> ()...)) + m_bind_function; +}; + +} /* namespace detail */ + +/* This is the "public" entry point. It's a macro to avoid having to + name FUNC more than once. */ + +#define FORWARD_SCOPE_EXIT(FUNC) \ + detail::forward_scope_exit<decltype (FUNC), FUNC, decltype (FUNC)> + +#endif /* COMMON_FORWARD_SCOPE_EXIT_H */ diff --git a/gdbsupport/function-view.h b/gdbsupport/function-view.h new file mode 100644 index 0000000..4e205b8 --- /dev/null +++ b/gdbsupport/function-view.h @@ -0,0 +1,323 @@ +/* Copyright (C) 2017-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_FUNCTION_VIEW_H +#define COMMON_FUNCTION_VIEW_H + +/* function_view is a polymorphic type-erasing wrapper class that + encapsulates a non-owning reference to arbitrary callable objects. + + A way to put it is that function_view is to std::function like + std::string_view is to std::string. While std::function stores a + type-erased callable object internally, function_view holds a + type-erased reference to an external callable object. + + This is meant to be used as callback type of a function that: + + #1 - Takes a callback as parameter. + + #2 - Wants to support arbitrary callable objects as callback type + (e.g., stateful function objects, lambda closures, free + functions). + + #3 - Does not store the callback anywhere; instead the function + just calls the callback directly or forwards it to some + other function that calls it. + + #4 - Can't be, or we don't want it to be, a template function + with the callable type as template parameter. For example, + when the callback is a parameter of a virtual member + function, or when putting the function template in a header + would expose too much implementation detail. + + Note that the C-style "function pointer" + "void *data" callback + parameter idiom fails requirement #2 above. Please don't add new + uses of that idiom. I.e., something like this wouldn't work; + + typedef bool (iterate_over_foos_cb) (foo *f, void *user_data), + void iterate_over_foos (iterate_over_foos_cb *callback, void *user_data); + + foo *find_foo_by_type (int type) + { + foo *found = nullptr; + + iterate_over_foos ([&] (foo *f, void *data) + { + if (foo->type == type) + { + found = foo; + return true; // stop iterating + } + return false; // continue iterating + }, NULL); + + return found; + } + + The above wouldn't compile, because lambdas with captures can't be + implicitly converted to a function pointer (because a capture means + some context data must be passed to the lambda somehow). + + C++11 gave us std::function as type-erased wrapper around arbitrary + callables, however, std::function is not an ideal fit for transient + callbacks such as the use case above. For this use case, which is + quite pervasive, a function_view is a better choice, because while + function_view is light and does not require any heap allocation, + std::function is a heavy-weight object with value semantics that + generally requires a heap allocation on construction/assignment of + the target callable. In addition, while it is possible to use + std::function in such a way that avoids most of the overhead by + making sure to only construct it with callables of types that fit + std::function's small object optimization, such as function + pointers and std::reference_wrapper callables, that is quite + inconvenient in practice, because restricting to free-function + callables would imply no state/capture/closure, which we need in + most cases, and std::reference_wrapper implies remembering to use + std::ref/std::cref where the callable is constructed, with the + added inconvenience that std::ref/std::cref have deleted rvalue-ref + overloads, meaning you can't use unnamed/temporary lambdas with + them. + + Note that because function_view is a non-owning view of a callable, + care must be taken to ensure that the callable outlives the + function_view that calls it. This is not really a problem for the + use case function_view is intended for, such as passing a temporary + function object / lambda to a function that accepts a callback, + because in those cases, the temporary is guaranteed to be live + until the called function returns. + + Calling a function_view with no associated target is undefined, + unlike with std::function, which throws std::bad_function_call. + This is by design, to avoid the otherwise necessary NULL check in + function_view::operator(). + + Since function_view objects are small (a pair of pointers), they + should generally be passed around by value. + + Usage: + + Given this function that accepts a callback: + + void + iterate_over_foos (gdb::function_view<void (foo *)> callback) + { + for (auto &foo : foos) + callback (&foo); + } + + you can call it like this, passing a lambda as callback: + + iterate_over_foos ([&] (foo *f) + { + process_one_foo (f); + }); + + or like this, passing a function object as callback: + + struct function_object + { + void operator() (foo *f) + { + if (s->check ()) + process_one_foo (f); + } + + // some state + state *s; + }; + + state mystate; + function_object matcher {&mystate}; + iterate_over_foos (matcher); + + or like this, passing a function pointer as callback: + + iterate_over_foos (process_one_foo); + + You can find unit tests covering the whole API in + unittests/function-view-selftests.c. */ + +namespace gdb { + +namespace fv_detail { +/* Bits shared by all function_view instantiations that do not depend + on the template parameters. */ + +/* Storage for the erased callable. This is a union in order to be + able to save both a function object (data) pointer or a function + pointer without triggering undefined behavior. */ +union erased_callable +{ + /* For function objects. */ + void *data; + + /* For function pointers. */ + void (*fn) (); +}; + +} /* namespace fv_detail */ + +/* Use partial specialization to get access to the callable's + signature. */ +template<class Signature> +struct function_view; + +template<typename Res, typename... Args> +class function_view<Res (Args...)> +{ + template<typename From, typename To> + using CompatibleReturnType + = Or<std::is_void<To>, + std::is_same<From, To>, + std::is_convertible<From, To>>; + + /* True if Func can be called with Args, and either the result is + Res, convertible to Res or Res is void. */ + template<typename Callable, + typename Res2 = typename std::result_of<Callable &(Args...)>::type> + struct IsCompatibleCallable : CompatibleReturnType<Res2, Res> + {}; + + /* True if Callable is a function_view. Used to avoid hijacking the + copy ctor. */ + template <typename Callable> + struct IsFunctionView + : std::is_same<function_view, typename std::decay<Callable>::type> + {}; + + public: + + /* NULL by default. */ + constexpr function_view () noexcept + : m_erased_callable {}, + m_invoker {} + {} + + /* Default copy/assignment is fine. */ + function_view (const function_view &) = default; + function_view &operator= (const function_view &) = default; + + /* This is the main entry point. Use SFINAE to avoid hijacking the + copy constructor and to ensure that the target type is + compatible. */ + template + <typename Callable, + typename = Requires<Not<IsFunctionView<Callable>>>, + typename = Requires<IsCompatibleCallable<Callable>>> + function_view (Callable &&callable) noexcept + { + bind (callable); + } + + /* Construct a NULL function_view. */ + constexpr function_view (std::nullptr_t) noexcept + : m_erased_callable {}, + m_invoker {} + {} + + /* Clear a function_view. */ + function_view &operator= (std::nullptr_t) noexcept + { + m_invoker = nullptr; + return *this; + } + + /* Return true if the wrapper has a target, false otherwise. Note + we check M_INVOKER instead of M_ERASED_CALLABLE because we don't + know which member of the union is active right now. */ + constexpr explicit operator bool () const noexcept + { return m_invoker != nullptr; } + + /* Call the callable. */ + Res operator () (Args... args) const + { return m_invoker (m_erased_callable, std::forward<Args> (args)...); } + + private: + + /* Bind this function_view to a compatible function object + reference. */ + template <typename Callable> + void bind (Callable &callable) noexcept + { + m_erased_callable.data = (void *) std::addressof (callable); + m_invoker = [] (fv_detail::erased_callable ecall, Args... args) + noexcept (noexcept (callable (std::forward<Args> (args)...))) -> Res + { + auto &restored_callable = *static_cast<Callable *> (ecall.data); + /* The explicit cast to Res avoids a compile error when Res is + void and the callable returns non-void. */ + return (Res) restored_callable (std::forward<Args> (args)...); + }; + } + + /* Bind this function_view to a compatible function pointer. + + Making this a separate function allows avoiding one indirection, + by storing the function pointer directly in the storage, instead + of a pointer to pointer. erased_callable is then a union in + order to avoid storing a function pointer as a data pointer here, + which would be undefined. */ + template<class Res2, typename... Args2> + void bind (Res2 (*fn) (Args2...)) noexcept + { + m_erased_callable.fn = reinterpret_cast<void (*) ()> (fn); + m_invoker = [] (fv_detail::erased_callable ecall, Args... args) + noexcept (noexcept (fn (std::forward<Args> (args)...))) -> Res + { + auto restored_fn = reinterpret_cast<Res2 (*) (Args2...)> (ecall.fn); + /* The explicit cast to Res avoids a compile error when Res is + void and the callable returns non-void. */ + return (Res) restored_fn (std::forward<Args> (args)...); + }; + } + + /* Storage for the erased callable. */ + fv_detail::erased_callable m_erased_callable; + + /* The invoker. This is set to a capture-less lambda by one of the + 'bind' overloads. The lambda restores the right type of the + callable (which is passed as first argument), and forwards the + args. */ + Res (*m_invoker) (fv_detail::erased_callable, Args...); +}; + +/* Allow comparison with NULL. Defer the work to the in-class + operator bool implementation. */ + +template<typename Res, typename... Args> +constexpr inline bool +operator== (const function_view<Res (Args...)> &f, std::nullptr_t) noexcept +{ return !static_cast<bool> (f); } + +template<typename Res, typename... Args> +constexpr inline bool +operator== (std::nullptr_t, const function_view<Res (Args...)> &f) noexcept +{ return !static_cast<bool> (f); } + +template<typename Res, typename... Args> +constexpr inline bool +operator!= (const function_view<Res (Args...)> &f, std::nullptr_t) noexcept +{ return static_cast<bool> (f); } + +template<typename Res, typename... Args> +constexpr inline bool +operator!= (std::nullptr_t, const function_view<Res (Args...)> &f) noexcept +{ return static_cast<bool> (f); } + +} /* namespace gdb */ + +#endif diff --git a/gdbsupport/gdb-dlfcn.c b/gdbsupport/gdb-dlfcn.c new file mode 100644 index 0000000..1a755bd --- /dev/null +++ b/gdbsupport/gdb-dlfcn.c @@ -0,0 +1,118 @@ +/* Platform independent shared object routines for GDB. + + Copyright (C) 2011-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "common-defs.h" +#include "gdb-dlfcn.h" + +#ifdef HAVE_DLFCN_H +#include <dlfcn.h> +#elif __MINGW32__ +#include <windows.h> +#else +/* Unsupported configuration. */ +#define NO_SHARED_LIB +#endif + +#ifdef NO_SHARED_LIB + +gdb_dlhandle_up +gdb_dlopen (const char *filename) +{ + gdb_assert_not_reached ("gdb_dlopen should not be called on this platform."); +} + +void * +gdb_dlsym (const gdb_dlhandle_up &handle, const char *symbol) +{ + gdb_assert_not_reached ("gdb_dlsym should not be called on this platform."); +} + +void +dlclose_deleter::operator() (void *handle) const +{ + gdb_assert_not_reached ("gdb_dlclose should not be called on this platform."); +} + +int +is_dl_available (void) +{ + return 0; +} + +#else /* NO_SHARED_LIB */ + +gdb_dlhandle_up +gdb_dlopen (const char *filename) +{ + void *result; +#ifdef HAVE_DLFCN_H + result = dlopen (filename, RTLD_NOW); +#elif __MINGW32__ + result = (void *) LoadLibrary (filename); +#endif + if (result != NULL) + return gdb_dlhandle_up (result); + +#ifdef HAVE_DLFCN_H + error (_("Could not load %s: %s"), filename, dlerror()); +#else + { + LPVOID buffer; + DWORD dw; + + dw = GetLastError(); + + FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR) &buffer, + 0, NULL); + + error (_("Could not load %s: %s"), filename, (char *) buffer); + } +#endif +} + +void * +gdb_dlsym (const gdb_dlhandle_up &handle, const char *symbol) +{ +#ifdef HAVE_DLFCN_H + return dlsym (handle.get (), symbol); +#elif __MINGW32__ + return (void *) GetProcAddress ((HMODULE) handle.get (), symbol); +#endif +} + +void +dlclose_deleter::operator() (void *handle) const +{ +#ifdef HAVE_DLFCN_H + dlclose (handle); +#elif __MINGW32__ + FreeLibrary ((HMODULE) handle); +#endif +} + +int +is_dl_available (void) +{ + return 1; +} + +#endif /* NO_SHARED_LIB */ diff --git a/gdbsupport/gdb-dlfcn.h b/gdbsupport/gdb-dlfcn.h new file mode 100644 index 0000000..258cfeb --- /dev/null +++ b/gdbsupport/gdb-dlfcn.h @@ -0,0 +1,51 @@ +/* Platform independent shared object routines for GDB. + + Copyright (C) 2011-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef GDB_DLFCN_H +#define GDB_DLFCN_H + +/* A deleter that closes an open dynamic library. */ + +struct dlclose_deleter +{ + void operator() (void *handle) const; +}; + +/* A unique pointer that points to a dynamic library. */ + +typedef std::unique_ptr<void, dlclose_deleter> gdb_dlhandle_up; + +/* Load the dynamic library file named FILENAME, and return a handle + for that dynamic library. Return NULL if the loading fails for any + reason. */ + +gdb_dlhandle_up gdb_dlopen (const char *filename); + +/* Return the address of the symbol named SYMBOL inside the shared + library whose handle is HANDLE. Return NULL when the symbol could + not be found. */ + +void *gdb_dlsym (const gdb_dlhandle_up &handle, const char *symbol); + +/* Return non-zero if the dynamic library functions are available on + this platform. */ + +int is_dl_available(void); + +#endif /* GDB_DLFCN_H */ diff --git a/gdbsupport/gdb-sigmask.h b/gdbsupport/gdb-sigmask.h new file mode 100644 index 0000000..cd58c54 --- /dev/null +++ b/gdbsupport/gdb-sigmask.h @@ -0,0 +1,45 @@ +/* sigprocmask wrapper for gdb + + Copyright (C) 2019-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef GDBSUPPORT_GDB_SIGMASK_H +#define GDBSUPPORT_GDB_SIGMASK_H + +#include <signal.h> + +#ifdef HAVE_SIGPROCMASK + +#ifdef HAVE_PTHREAD_SIGMASK +#define gdb_sigmask pthread_sigmask +#else +#define gdb_sigmask sigprocmask +#endif + +#else /* HAVE_SIGPROCMASK */ + +/* Other code checks HAVE_SIGPROCMASK, but if there happened to be a + system that only had pthread_sigmask, we could still use it with + some extra changes. */ +#ifdef HAVE_PTHREAD_SIGMASK +#error pthead_sigmask available without sigprocmask - please report +#endif + +#endif /* HAVE_SIGPROCMASK */ + + +#endif /* GDBSUPPORT_GDB_SIGMASK_H */ diff --git a/gdbsupport/gdb_assert.h b/gdbsupport/gdb_assert.h new file mode 100644 index 0000000..3936003 --- /dev/null +++ b/gdbsupport/gdb_assert.h @@ -0,0 +1,61 @@ +/* GDB-friendly replacement for <assert.h>. + Copyright (C) 2000-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_GDB_ASSERT_H +#define COMMON_GDB_ASSERT_H + +#include "errors.h" + +/* A static assertion. This will cause a compile-time error if EXPR, + which must be a compile-time constant, is false. */ + +#define gdb_static_assert(expr) static_assert (expr, "") + +/* PRAGMATICS: "gdb_assert.h":gdb_assert() is a lower case (rather + than upper case) macro since that provides the closest fit to the + existing lower case macro <assert.h>:assert() that it is + replacing. */ + +#define gdb_assert(expr) \ + ((void) ((expr) ? 0 : \ + (gdb_assert_fail (#expr, __FILE__, __LINE__, FUNCTION_NAME), 0))) + +/* This prints an "Assertion failed" message, asking the user if they + want to continue, dump core, or just exit. */ +#if defined (FUNCTION_NAME) +#define gdb_assert_fail(assertion, file, line, function) \ + internal_error (file, line, _("%s: Assertion `%s' failed."), \ + function, assertion) +#else +#define gdb_assert_fail(assertion, file, line, function) \ + internal_error (file, line, _("Assertion `%s' failed."), \ + assertion) +#endif + +/* The canonical form of gdb_assert (0). + MESSAGE is a string to include in the error message. */ + +#if defined (FUNCTION_NAME) +#define gdb_assert_not_reached(message) \ + internal_error (__FILE__, __LINE__, "%s: %s", FUNCTION_NAME, _(message)) +#else +#define gdb_assert_not_reached(message) \ + internal_error (__FILE__, __LINE__, _(message)) +#endif + +#endif /* COMMON_GDB_ASSERT_H */ diff --git a/gdbsupport/gdb_binary_search.h b/gdbsupport/gdb_binary_search.h new file mode 100644 index 0000000..a456015 --- /dev/null +++ b/gdbsupport/gdb_binary_search.h @@ -0,0 +1,59 @@ +/* C++ implementation of a binary search. + + Copyright (C) 2019-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + + +#ifndef GDBSUPPORT_GDB_BINARY_SEARCH_H +#define GDBSUPPORT_GDB_BINARY_SEARCH_H + +#include <algorithm> + +namespace gdb { + +/* Implements a binary search using C++ iterators. + This differs from std::binary_search in that it returns an interator for + the found element and in that the type of EL can be different from the + type of the elements in the countainer. + + COMP is a C-style comparison function with signature: + int comp(const value_type& a, const T& b); + It should return -1, 0 or 1 if a is less than, equal to, or greater than + b, respectively. + [first, last) must be sorted. + + The return value is an iterator pointing to the found element, or LAST if + no element was found. */ +template<typename It, typename T, typename Comp> +It binary_search (It first, It last, T el, Comp comp) +{ + auto lt = [&] (const typename std::iterator_traits<It>::value_type &a, + const T &b) + { return comp (a, b) < 0; }; + + auto lb = std::lower_bound (first, last, el, lt); + if (lb != last) + { + if (comp (*lb, el) == 0) + return lb; + } + return last; +} + +} /* namespace gdb */ + +#endif /* GDBSUPPORT_GDB_BINARY_SEARCH_H */ diff --git a/gdbsupport/gdb_locale.h b/gdbsupport/gdb_locale.h new file mode 100644 index 0000000..a1d0b67 --- /dev/null +++ b/gdbsupport/gdb_locale.h @@ -0,0 +1,43 @@ +/* GDB-friendly replacement for <locale.h>. + Copyright (C) 2002-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_GDB_LOCALE_H +#define COMMON_GDB_LOCALE_H + +#ifdef HAVE_LOCALE_H +# include <locale.h> +#endif + +#ifdef ENABLE_NLS +# include <libintl.h> +# define _(String) gettext (String) +# ifdef gettext_noop +# define N_(String) gettext_noop (String) +# else +# define N_(String) (String) +# endif +#else +# define _(String) (String) +# define N_(String) (String) +#endif + +#ifdef HAVE_LANGINFO_CODESET +#include <langinfo.h> +#endif + +#endif /* COMMON_GDB_LOCALE_H */ diff --git a/gdbsupport/gdb_optional.h b/gdbsupport/gdb_optional.h new file mode 100644 index 0000000..02a87f6 --- /dev/null +++ b/gdbsupport/gdb_optional.h @@ -0,0 +1,219 @@ +/* An optional object. + + Copyright (C) 2017-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_GDB_OPTIONAL_H +#define COMMON_GDB_OPTIONAL_H + +#include "gdbsupport/traits.h" + +namespace gdb +{ + +struct in_place_t +{ + explicit in_place_t () = default; +}; + +constexpr gdb::in_place_t in_place {}; + +/* This class attempts to be a compatible subset of std::optional, + which is slated to be available in C++17. This class optionally + holds an object of some type -- by default it is constructed not + holding an object, but later the object can be "emplaced". This is + similar to using std::unique_ptr, but in-object allocation is + guaranteed. + + Unlike std::optional, we currently only support copy/move + construction/assignment of an optional<T> from either exactly + optional<T> or T. I.e., we don't support copy/move + construction/assignment from optional<U> or U, when U is a type + convertible to T. Making that work depending on the definitions of + T and U is somewhat complicated, and currently the users of this + class don't need it. */ + +template<typename T> +class optional +{ +public: + + constexpr optional () + : m_dummy () + {} + + template<typename... Args> + constexpr optional (in_place_t, Args &&... args) + : m_item (std::forward<Args> (args)...), + m_instantiated (true) + {} + + ~optional () + { this->reset (); } + + /* Copy and move constructors. */ + + optional (const optional &other) + { + if (other.m_instantiated) + this->emplace (other.get ()); + } + + optional (optional &&other) + noexcept(std::is_nothrow_move_constructible<T> ()) + { + if (other.m_instantiated) + this->emplace (std::move (other.get ())); + } + + constexpr optional (const T &other) + : m_item (other), + m_instantiated (true) + {} + + constexpr optional (T &&other) + noexcept (std::is_nothrow_move_constructible<T> ()) + : m_item (std::move (other)), + m_instantiated (true) + {} + + /* Assignment operators. */ + + optional & + operator= (const optional &other) + { + if (m_instantiated && other.m_instantiated) + this->get () = other.get (); + else + { + if (other.m_instantiated) + this->emplace (other.get ()); + else + this->reset (); + } + + return *this; + } + + optional & + operator= (optional &&other) + noexcept (And<std::is_nothrow_move_constructible<T>, + std::is_nothrow_move_assignable<T>> ()) + { + if (m_instantiated && other.m_instantiated) + this->get () = std::move (other.get ()); + else + { + if (other.m_instantiated) + this->emplace (std::move (other.get ())); + else + this->reset (); + } + return *this; + } + + optional & + operator= (const T &other) + { + if (m_instantiated) + this->get () = other; + else + this->emplace (other); + return *this; + } + + optional & + operator= (T &&other) + noexcept (And<std::is_nothrow_move_constructible<T>, + std::is_nothrow_move_assignable<T>> ()) + { + if (m_instantiated) + this->get () = std::move (other); + else + this->emplace (std::move (other)); + return *this; + } + + template<typename... Args> + T &emplace (Args &&... args) + { + this->reset (); + new (&m_item) T (std::forward<Args>(args)...); + m_instantiated = true; + return this->get (); + } + + /* Observers. */ + constexpr const T *operator-> () const + { return std::addressof (this->get ()); } + + T *operator-> () + { return std::addressof (this->get ()); } + + constexpr const T &operator* () const & + { return this->get (); } + + T &operator* () & + { return this->get (); } + + T &&operator* () && + { return std::move (this->get ()); } + + constexpr const T &&operator* () const && + { return std::move (this->get ()); } + + constexpr explicit operator bool () const noexcept + { return m_instantiated; } + + constexpr bool has_value () const noexcept + { return m_instantiated; } + + /* 'reset' is a 'safe' operation with no precondition. */ + void reset () noexcept + { + if (m_instantiated) + this->destroy (); + } + +private: + + /* Destroy the object. */ + void destroy () + { + gdb_assert (m_instantiated); + m_instantiated = false; + m_item.~T (); + } + + /* The get operations have m_instantiated as a precondition. */ + T &get () noexcept { return m_item; } + constexpr const T &get () const noexcept { return m_item; } + + /* The object. */ + union + { + struct { } m_dummy; + T m_item; + }; + + /* True if the object was ever emplaced. */ + bool m_instantiated = false; +}; + +} + +#endif /* COMMON_GDB_OPTIONAL_H */ diff --git a/gdbsupport/gdb_proc_service.h b/gdbsupport/gdb_proc_service.h new file mode 100644 index 0000000..3ce2ee8 --- /dev/null +++ b/gdbsupport/gdb_proc_service.h @@ -0,0 +1,173 @@ +/* <proc_service.h> replacement for systems that don't have it. + Copyright (C) 2000-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_GDB_PROC_SERVICE_H +#define COMMON_GDB_PROC_SERVICE_H + +#include <sys/types.h> + +#ifdef HAVE_PROC_SERVICE_H + +/* glibc's proc_service.h doesn't wrap itself with extern "C". Need + to do it ourselves. */ +EXTERN_C_PUSH + +#include <proc_service.h> + +EXTERN_C_POP + +#else /* HAVE_PROC_SERVICE_H */ + +/* The following fallback definitions have been imported and adjusted + from glibc's proc_service.h */ + +/* Callback interface for libthread_db, functions users must define. + Copyright (C) 1999,2002,2003 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +/* The definitions in this file must correspond to those in the debugger. */ + +#ifdef HAVE_SYS_PROCFS_H +#include <sys/procfs.h> +#endif + +/* Not all platforms bring in <linux/elf.h> via <sys/procfs.h>. If + <sys/procfs.h> wasn't enough to find elf_fpregset_t, try the kernel + headers also (but don't if we don't need to). */ +#ifndef HAVE_ELF_FPREGSET_T +# ifdef HAVE_LINUX_ELF_H +# include <linux/elf.h> +# endif +#endif + +EXTERN_C_PUSH + +/* Functions in this interface return one of these status codes. */ +typedef enum +{ + PS_OK, /* Generic "call succeeded". */ + PS_ERR, /* Generic error. */ + PS_BADPID, /* Bad process handle. */ + PS_BADLID, /* Bad LWP identifier. */ + PS_BADADDR, /* Bad address. */ + PS_NOSYM, /* Could not find given symbol. */ + PS_NOFREGS /* FPU register set not available for given LWP. */ +} ps_err_e; + +#ifndef HAVE_LWPID_T +typedef unsigned int lwpid_t; +#endif + +#ifndef HAVE_PSADDR_T +typedef void *psaddr_t; +#endif + +#ifndef HAVE_PRGREGSET_T +typedef elf_gregset_t prgregset_t; +#endif + +#ifndef HAVE_PRFPREGSET_T +typedef elf_fpregset_t prfpregset_t; +#endif + +/* This type is opaque in this interface. It's defined by the user of + libthread_db. GDB's version is defined below. */ +struct ps_prochandle; + + +/* Read or write process memory at the given address. */ +extern ps_err_e ps_pdread (struct ps_prochandle *, + psaddr_t, void *, size_t); +extern ps_err_e ps_pdwrite (struct ps_prochandle *, + psaddr_t, const void *, size_t); +extern ps_err_e ps_ptread (struct ps_prochandle *, + psaddr_t, void *, size_t); +extern ps_err_e ps_ptwrite (struct ps_prochandle *, + psaddr_t, const void *, size_t); + + +/* Get and set the given LWP's general or FPU register set. */ +extern ps_err_e ps_lgetregs (struct ps_prochandle *, + lwpid_t, prgregset_t); +extern ps_err_e ps_lsetregs (struct ps_prochandle *, + lwpid_t, const prgregset_t); +extern ps_err_e ps_lgetfpregs (struct ps_prochandle *, + lwpid_t, prfpregset_t *); +extern ps_err_e ps_lsetfpregs (struct ps_prochandle *, + lwpid_t, const prfpregset_t *); + +/* Return the PID of the process. */ +extern pid_t ps_getpid (struct ps_prochandle *); + +/* Fetch the special per-thread address associated with the given LWP. + This call is only used on a few platforms (most use a normal register). + The meaning of the `int' parameter is machine-dependent. */ +extern ps_err_e ps_get_thread_area (struct ps_prochandle *, + lwpid_t, int, psaddr_t *); + + +/* Look up the named symbol in the named DSO in the symbol tables + associated with the process being debugged, filling in *SYM_ADDR + with the corresponding run-time address. */ +extern ps_err_e ps_pglobal_lookup (struct ps_prochandle *, + const char *object_name, + const char *sym_name, + psaddr_t *sym_addr); + + +/* Stop or continue the entire process. */ +extern ps_err_e ps_pstop (struct ps_prochandle *); +extern ps_err_e ps_pcontinue (struct ps_prochandle *); + +/* Stop or continue the given LWP alone. */ +extern ps_err_e ps_lstop (struct ps_prochandle *, lwpid_t); +extern ps_err_e ps_lcontinue (struct ps_prochandle *, lwpid_t); + +/* The following are only defined in/called by Solaris. */ + +/* Get size of extra register set. */ +extern ps_err_e ps_lgetxregsize (struct ps_prochandle *ph, + lwpid_t lwpid, int *xregsize); +/* Get extra register set. */ +extern ps_err_e ps_lgetxregs (struct ps_prochandle *ph, lwpid_t lwpid, + caddr_t xregset); +extern ps_err_e ps_lsetxregs (struct ps_prochandle *ph, lwpid_t lwpid, + caddr_t xregset); + +/* Log a message (sends to gdb_stderr). */ +extern void ps_plog (const char *fmt, ...); + +EXTERN_C_POP + +#endif /* HAVE_PROC_SERVICE_H */ + +#endif /* COMMON_GDB_PROC_SERVICE_H */ diff --git a/gdbsupport/gdb_ref_ptr.h b/gdbsupport/gdb_ref_ptr.h new file mode 100644 index 0000000..c5ef13f --- /dev/null +++ b/gdbsupport/gdb_ref_ptr.h @@ -0,0 +1,228 @@ +/* Reference-counted smart pointer class + + Copyright (C) 2016-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_GDB_REF_PTR_H +#define COMMON_GDB_REF_PTR_H + +#include <cstddef> + +namespace gdb +{ + +/* An instance of this class either holds a reference to a + reference-counted object or is "NULL". Reference counting is + handled externally by a policy class. If the object holds a + reference, then when the object is destroyed, the reference is + decref'd. + + Normally an instance is constructed using a pointer. This sort of + initialization lets this class manage the lifetime of that + reference. + + Assignment and copy construction will make a new reference as + appropriate. Assignment from a plain pointer is disallowed to + avoid confusion about whether this acquires a new reference; + instead use the "reset" method -- which, like the pointer + constructor, transfers ownership. + + The policy class must provide two static methods: + void incref (T *); + void decref (T *); +*/ +template<typename T, typename Policy> +class ref_ptr +{ + public: + + /* Create a new NULL instance. */ + ref_ptr () + : m_obj (NULL) + { + } + + /* Create a new NULL instance. Note that this is not explicit. */ + ref_ptr (const std::nullptr_t) + : m_obj (NULL) + { + } + + /* Create a new instance. OBJ is a reference, management of which + is now transferred to this class. */ + explicit ref_ptr (T *obj) + : m_obj (obj) + { + } + + /* Copy another instance. */ + ref_ptr (const ref_ptr &other) + : m_obj (other.m_obj) + { + if (m_obj != NULL) + Policy::incref (m_obj); + } + + /* Transfer ownership from OTHER. */ + ref_ptr (ref_ptr &&other) + : m_obj (other.m_obj) + { + other.m_obj = NULL; + } + + /* Destroy this instance. */ + ~ref_ptr () + { + if (m_obj != NULL) + Policy::decref (m_obj); + } + + /* Copy another instance. */ + ref_ptr &operator= (const ref_ptr &other) + { + /* Do nothing on self-assignment. */ + if (this != &other) + { + reset (other.m_obj); + if (m_obj != NULL) + Policy::incref (m_obj); + } + return *this; + } + + /* Transfer ownership from OTHER. */ + ref_ptr &operator= (ref_ptr &&other) + { + /* Do nothing on self-assignment. */ + if (this != &other) + { + reset (other.m_obj); + other.m_obj = NULL; + } + return *this; + } + + /* Change this instance's referent. OBJ is a reference, management + of which is now transferred to this class. */ + void reset (T *obj) + { + if (m_obj != NULL) + Policy::decref (m_obj); + m_obj = obj; + } + + /* Return this instance's referent without changing the state of + this class. */ + T *get () const + { + return m_obj; + } + + /* Return this instance's referent, and stop managing this + reference. The caller is now responsible for the ownership of + the reference. */ + ATTRIBUTE_UNUSED_RESULT T *release () + { + T *result = m_obj; + + m_obj = NULL; + return result; + } + + /* Let users refer to members of the underlying pointer. */ + T *operator-> () const + { + return m_obj; + } + + /* Acquire a new reference and return a ref_ptr that owns it. */ + static ref_ptr<T, Policy> new_reference (T *obj) + { + Policy::incref (obj); + return ref_ptr<T, Policy> (obj); + } + + private: + + T *m_obj; +}; + +template<typename T, typename Policy> +inline bool operator== (const ref_ptr<T, Policy> &lhs, + const ref_ptr<T, Policy> &rhs) +{ + return lhs.get () == rhs.get (); +} + +template<typename T, typename Policy> +inline bool operator== (const ref_ptr<T, Policy> &lhs, const T *rhs) +{ + return lhs.get () == rhs; +} + +template<typename T, typename Policy> +inline bool operator== (const ref_ptr<T, Policy> &lhs, const std::nullptr_t) +{ + return lhs.get () == nullptr; +} + +template<typename T, typename Policy> +inline bool operator== (const T *lhs, const ref_ptr<T, Policy> &rhs) +{ + return lhs == rhs.get (); +} + +template<typename T, typename Policy> +inline bool operator== (const std::nullptr_t, const ref_ptr<T, Policy> &rhs) +{ + return nullptr == rhs.get (); +} + +template<typename T, typename Policy> +inline bool operator!= (const ref_ptr<T, Policy> &lhs, + const ref_ptr<T, Policy> &rhs) +{ + return lhs.get () != rhs.get (); +} + +template<typename T, typename Policy> +inline bool operator!= (const ref_ptr<T, Policy> &lhs, const T *rhs) +{ + return lhs.get () != rhs; +} + +template<typename T, typename Policy> +inline bool operator!= (const ref_ptr<T, Policy> &lhs, const std::nullptr_t) +{ + return lhs.get () != nullptr; +} + +template<typename T, typename Policy> +inline bool operator!= (const T *lhs, const ref_ptr<T, Policy> &rhs) +{ + return lhs != rhs.get (); +} + +template<typename T, typename Policy> +inline bool operator!= (const std::nullptr_t, const ref_ptr<T, Policy> &rhs) +{ + return nullptr != rhs.get (); +} + +} + +#endif /* COMMON_GDB_REF_PTR_H */ diff --git a/gdbsupport/gdb_setjmp.h b/gdbsupport/gdb_setjmp.h new file mode 100644 index 0000000..168833a --- /dev/null +++ b/gdbsupport/gdb_setjmp.h @@ -0,0 +1,36 @@ +/* Portability wrappers for setjmp and longjmp. + Copyright (C) 1986-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_GDB_SETJMP_H +#define COMMON_GDB_SETJMP_H + +#include <setjmp.h> + +#ifdef HAVE_SIGSETJMP +#define SIGJMP_BUF sigjmp_buf +#define SIGSETJMP(buf,val) sigsetjmp((buf), val) +#define SIGLONGJMP(buf,val) siglongjmp((buf), (val)) +#else +#define SIGJMP_BUF jmp_buf +/* We ignore val here because that's safer and avoids having to check + whether _setjmp exists. */ +#define SIGSETJMP(buf,val) setjmp(buf) +#define SIGLONGJMP(buf,val) longjmp((buf), (val)) +#endif + +#endif /* COMMON_GDB_SETJMP_H */ diff --git a/gdbsupport/gdb_signals.h b/gdbsupport/gdb_signals.h new file mode 100644 index 0000000..fbbb7be --- /dev/null +++ b/gdbsupport/gdb_signals.h @@ -0,0 +1,58 @@ +/* Target signal translation functions for GDB. + Copyright (C) 1990-2020 Free Software Foundation, Inc. + Contributed by Cygnus Support. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_GDB_SIGNALS_H +#define COMMON_GDB_SIGNALS_H + +#include "gdb/signals.h" + +/* Predicate to gdb_signal_to_host(). Return non-zero if the enum + targ_signal SIGNO has an equivalent ``host'' representation. */ +/* FIXME: cagney/1999-11-22: The name below was chosen in preference + to the shorter gdb_signal_p() because it is far less ambigious. + In this context ``gdb_signal'' refers to GDB's internal + representation of the target's set of signals while ``host signal'' + refers to the target operating system's signal. Confused? */ +extern int gdb_signal_to_host_p (enum gdb_signal signo); + +/* Convert between host signal numbers and enum gdb_signal's. + gdb_signal_to_host() returns 0 and prints a warning() on GDB's + console if SIGNO has no equivalent host representation. */ +/* FIXME: cagney/1999-11-22: Here ``host'' is used incorrectly, it is + refering to the target operating system's signal numbering. + Similarly, ``enum gdb_signal'' is named incorrectly, ``enum + gdb_signal'' would probably be better as it is refering to GDB's + internal representation of a target operating system's signal. */ +extern enum gdb_signal gdb_signal_from_host (int); +extern int gdb_signal_to_host (enum gdb_signal); + +/* Return the enum symbol name of SIG as a string, to use in debug + output. */ +extern const char *gdb_signal_to_symbol_string (enum gdb_signal sig); + +/* Return the string for a signal. */ +extern const char *gdb_signal_to_string (enum gdb_signal); + +/* Return the name (SIGHUP, etc.) for a signal. */ +extern const char *gdb_signal_to_name (enum gdb_signal); + +/* Given a name (SIGHUP, etc.), return its signal. */ +enum gdb_signal gdb_signal_from_name (const char *); + +#endif /* COMMON_GDB_SIGNALS_H */ diff --git a/gdbsupport/gdb_splay_tree.h b/gdbsupport/gdb_splay_tree.h new file mode 100644 index 0000000..b0f533e --- /dev/null +++ b/gdbsupport/gdb_splay_tree.h @@ -0,0 +1,42 @@ +/* GDB wrapper for splay trees. + + Copyright (C) 2017-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_GDB_SPLAY_TREE_H +#define COMMON_GDB_SPLAY_TREE_H + +#include "splay-tree.h" + +namespace gdb { + +struct splay_tree_deleter +{ + void operator() (splay_tree tree) const + { + splay_tree_delete (tree); + } +}; + +} /* namespace gdb */ + +/* A unique pointer to a splay tree. */ + +typedef std::unique_ptr<splay_tree_s, gdb::splay_tree_deleter> + gdb_splay_tree_up; + +#endif /* COMMON_GDB_SPLAY_TREE_H */ diff --git a/gdbsupport/gdb_string_view.h b/gdbsupport/gdb_string_view.h new file mode 100644 index 0000000..c0ae7a8 --- /dev/null +++ b/gdbsupport/gdb_string_view.h @@ -0,0 +1,563 @@ +// Components for manipulating non-owning sequences of characters -*- C++ -*- + + +#ifndef COMMON_GDB_STRING_VIEW_H +#define COMMON_GDB_STRING_VIEW_H + +// Note: This file has been stolen from the gcc repo +// (libstdc++-v3/include/experimental/string_view) and has local modifications. + +// Copyright (C) 2013-2020 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +// +// N3762 basic_string_view library +// + + +#if __cplusplus >= 201703L + +#include <string_view> + +namespace gdb { + using string_view = std::string_view; +} /* namespace gdb */ + +#else /* __cplusplus < 201703L */ + +#include <string> +#include <limits> +#include "gdb_assert.h" + +namespace gdb { + + /** + * @class basic_string_view <experimental/string_view> + * @brief A non-owning reference to a string. + * + * @ingroup strings + * @ingroup sequences + * @ingroup experimental + * + * @tparam _CharT Type of character + * @tparam _Traits Traits for character type, defaults to + * char_traits<_CharT>. + * + * A basic_string_view looks like this: + * + * @code + * _CharT* _M_str + * size_t _M_len + * @endcode + */ + template<typename _CharT, typename _Traits = std::char_traits<_CharT>> + class basic_string_view + { + public: + + // types + using traits_type = _Traits; + using value_type = _CharT; + using pointer = const _CharT*; + using const_pointer = const _CharT*; + using reference = const _CharT&; + using const_reference = const _CharT&; + using const_iterator = const _CharT*; + using iterator = const_iterator; + using const_reverse_iterator = std::reverse_iterator<const_iterator>; + using reverse_iterator = const_reverse_iterator; + using size_type = size_t; + using difference_type = ptrdiff_t; + static constexpr size_type npos = size_type(-1); + + // [string.view.cons], construct/copy + + constexpr + basic_string_view() noexcept + : _M_len{0}, _M_str{nullptr} + { } + + constexpr basic_string_view(const basic_string_view&) noexcept = default; + + template<typename _Allocator> + basic_string_view(const std::basic_string<_CharT, _Traits, + _Allocator>& __str) noexcept + : _M_len{__str.length()}, _M_str{__str.data()} + { } + + /*constexpr*/ basic_string_view(const _CharT* __str) + : _M_len{__str == nullptr ? 0 : traits_type::length(__str)}, + _M_str{__str} + { } + + constexpr basic_string_view(const _CharT* __str, size_type __len) + : _M_len{__len}, + _M_str{__str} + { } + + basic_string_view& + operator=(const basic_string_view&) noexcept = default; + + // [string.view.iterators], iterators + + constexpr const_iterator + begin() const noexcept + { return this->_M_str; } + + constexpr const_iterator + end() const noexcept + { return this->_M_str + this->_M_len; } + + constexpr const_iterator + cbegin() const noexcept + { return this->_M_str; } + + constexpr const_iterator + cend() const noexcept + { return this->_M_str + this->_M_len; } + + const_reverse_iterator + rbegin() const noexcept + { return const_reverse_iterator(this->end()); } + + const_reverse_iterator + rend() const noexcept + { return const_reverse_iterator(this->begin()); } + + const_reverse_iterator + crbegin() const noexcept + { return const_reverse_iterator(this->end()); } + + const_reverse_iterator + crend() const noexcept + { return const_reverse_iterator(this->begin()); } + + // [string.view.capacity], capacity + + constexpr size_type + size() const noexcept + { return this->_M_len; } + + constexpr size_type + length() const noexcept + { return _M_len; } + + constexpr size_type + max_size() const noexcept + { + return (npos - sizeof(size_type) - sizeof(void*)) + / sizeof(value_type) / 4; + } + + constexpr bool + empty() const noexcept + { return this->_M_len == 0; } + + // [string.view.access], element access + + constexpr const _CharT& + operator[](size_type __pos) const + { + // TODO: Assert to restore in a way compatible with the constexpr. + // __glibcxx_assert(__pos < this->_M_len); + return *(this->_M_str + __pos); + } + + constexpr const _CharT& + at(size_type __pos) const + { + return __pos < this->_M_len + ? *(this->_M_str + __pos) + : (error (_("basic_string_view::at: __pos " + "(which is %zu) >= this->size() " + "(which is %zu)"), + __pos, this->size()), + *this->_M_str); + } + + constexpr const _CharT& + front() const + { + // TODO: Assert to restore in a way compatible with the constexpr. + // __glibcxx_assert(this->_M_len > 0); + return *this->_M_str; + } + + constexpr const _CharT& + back() const + { + // TODO: Assert to restore in a way compatible with the constexpr. + // __glibcxx_assert(this->_M_len > 0); + return *(this->_M_str + this->_M_len - 1); + } + + constexpr const _CharT* + data() const noexcept + { return this->_M_str; } + + // [string.view.modifiers], modifiers: + + /*constexpr*/ void + remove_prefix(size_type __n) + { + gdb_assert (this->_M_len >= __n); + this->_M_str += __n; + this->_M_len -= __n; + } + + /*constexpr*/ void + remove_suffix(size_type __n) + { this->_M_len -= __n; } + + /*constexpr*/ void + swap(basic_string_view& __sv) noexcept + { + auto __tmp = *this; + *this = __sv; + __sv = __tmp; + } + + + // [string.view.ops], string operations: + + template<typename _Allocator> + explicit operator std::basic_string<_CharT, _Traits, _Allocator>() const + { + return { this->_M_str, this->_M_len }; + } + + template<typename _Allocator = std::allocator<_CharT>> + std::basic_string<_CharT, _Traits, _Allocator> + to_string(const _Allocator& __alloc = _Allocator()) const + { + return { this->_M_str, this->_M_len, __alloc }; + } + + size_type + copy(_CharT* __str, size_type __n, size_type __pos = 0) const + { + gdb_assert (__str != nullptr || __n == 0); + if (__pos > this->_M_len) + error (_("basic_string_view::copy: __pos " + "(which is %zu) > this->size() " + "(which is %zu)"), + __pos, this->size()); + size_type __rlen{std::min(__n, size_type{this->_M_len - __pos})}; + for (auto __begin = this->_M_str + __pos, + __end = __begin + __rlen; __begin != __end;) + *__str++ = *__begin++; + return __rlen; + } + + + // [string.view.ops], string operations: + + /*constexpr*/ basic_string_view + substr(size_type __pos, size_type __n=npos) const + { + return __pos <= this->_M_len + ? basic_string_view{this->_M_str + __pos, + std::min(__n, size_type{this->_M_len - __pos})} + : (error (_("basic_string_view::substr: __pos " + "(which is %zu) > this->size() " + "(which is %zu)"), + __pos, this->size()), basic_string_view{}); + } + + /*constexpr*/ int + compare(basic_string_view __str) const noexcept + { + int __ret = traits_type::compare(this->_M_str, __str._M_str, + std::min(this->_M_len, __str._M_len)); + if (__ret == 0) + __ret = _S_compare(this->_M_len, __str._M_len); + return __ret; + } + + /*constexpr*/ int + compare(size_type __pos1, size_type __n1, basic_string_view __str) const + { return this->substr(__pos1, __n1).compare(__str); } + + /*constexpr*/ int + compare(size_type __pos1, size_type __n1, + basic_string_view __str, size_type __pos2, size_type __n2) const + { return this->substr(__pos1, __n1).compare(__str.substr(__pos2, __n2)); } + + /*constexpr*/ int + compare(const _CharT* __str) const noexcept + { return this->compare(basic_string_view{__str}); } + + /*constexpr*/ int + compare(size_type __pos1, size_type __n1, const _CharT* __str) const + { return this->substr(__pos1, __n1).compare(basic_string_view{__str}); } + + /*constexpr*/ int + compare(size_type __pos1, size_type __n1, + const _CharT* __str, size_type __n2) const + { + return this->substr(__pos1, __n1) + .compare(basic_string_view(__str, __n2)); + } + + /*constexpr*/ size_type + find(basic_string_view __str, size_type __pos = 0) const noexcept + { return this->find(__str._M_str, __pos, __str._M_len); } + + /*constexpr*/ size_type + find(_CharT __c, size_type __pos=0) const noexcept; + + /*constexpr*/ size_type + find(const _CharT* __str, size_type __pos, size_type __n) const noexcept; + + /*constexpr*/ size_type + find(const _CharT* __str, size_type __pos=0) const noexcept + { return this->find(__str, __pos, traits_type::length(__str)); } + + /*constexpr*/ size_type + rfind(basic_string_view __str, size_type __pos = npos) const noexcept + { return this->rfind(__str._M_str, __pos, __str._M_len); } + + /*constexpr*/ size_type + rfind(_CharT __c, size_type __pos = npos) const noexcept; + + /*constexpr*/ size_type + rfind(const _CharT* __str, size_type __pos, size_type __n) const noexcept; + + /*constexpr*/ size_type + rfind(const _CharT* __str, size_type __pos = npos) const noexcept + { return this->rfind(__str, __pos, traits_type::length(__str)); } + + /*constexpr*/ size_type + find_first_of(basic_string_view __str, size_type __pos = 0) const noexcept + { return this->find_first_of(__str._M_str, __pos, __str._M_len); } + + /*constexpr*/ size_type + find_first_of(_CharT __c, size_type __pos = 0) const noexcept + { return this->find(__c, __pos); } + + /*constexpr*/ size_type + find_first_of(const _CharT* __str, size_type __pos, size_type __n) const; + + /*constexpr*/ size_type + find_first_of(const _CharT* __str, size_type __pos = 0) const noexcept + { return this->find_first_of(__str, __pos, traits_type::length(__str)); } + + /*constexpr*/ size_type + find_last_of(basic_string_view __str, + size_type __pos = npos) const noexcept + { return this->find_last_of(__str._M_str, __pos, __str._M_len); } + + size_type + find_last_of(_CharT __c, size_type __pos=npos) const noexcept + { return this->rfind(__c, __pos); } + + /*constexpr*/ size_type + find_last_of(const _CharT* __str, size_type __pos, size_type __n) const; + + /*constexpr*/ size_type + find_last_of(const _CharT* __str, size_type __pos = npos) const noexcept + { return this->find_last_of(__str, __pos, traits_type::length(__str)); } + + /*constexpr*/ size_type + find_first_not_of(basic_string_view __str, + size_type __pos = 0) const noexcept + { return this->find_first_not_of(__str._M_str, __pos, __str._M_len); } + + /*constexpr*/ size_type + find_first_not_of(_CharT __c, size_type __pos = 0) const noexcept; + + /*constexpr*/ size_type + find_first_not_of(const _CharT* __str, + size_type __pos, size_type __n) const; + + /*constexpr*/ size_type + find_first_not_of(const _CharT* __str, size_type __pos = 0) const noexcept + { + return this->find_first_not_of(__str, __pos, + traits_type::length(__str)); + } + + /*constexpr*/ size_type + find_last_not_of(basic_string_view __str, + size_type __pos = npos) const noexcept + { return this->find_last_not_of(__str._M_str, __pos, __str._M_len); } + + /*constexpr*/ size_type + find_last_not_of(_CharT __c, size_type __pos = npos) const noexcept; + + /*constexpr*/ size_type + find_last_not_of(const _CharT* __str, + size_type __pos, size_type __n) const; + + /*constexpr*/ size_type + find_last_not_of(const _CharT* __str, + size_type __pos = npos) const noexcept + { + return this->find_last_not_of(__str, __pos, + traits_type::length(__str)); + } + + private: + + static constexpr int + _S_compare(size_type __n1, size_type __n2) noexcept + { + return difference_type(__n1 - __n2) > std::numeric_limits<int>::max() + ? std::numeric_limits<int>::max() + : difference_type(__n1 - __n2) < std::numeric_limits<int>::min() + ? std::numeric_limits<int>::min() + : static_cast<int>(difference_type(__n1 - __n2)); + } + + size_t _M_len; + const _CharT* _M_str; + }; + + // [string.view.comparison], non-member basic_string_view comparison functions + + namespace __detail + { + // Identity transform to create a non-deduced context, so that only one + // argument participates in template argument deduction and the other + // argument gets implicitly converted to the deduced type. See n3766.html. + template<typename _Tp> + using __idt = typename std::common_type<_Tp>::type; + } + + template<typename _CharT, typename _Traits> + /*constexpr*/ bool + operator==(basic_string_view<_CharT, _Traits> __x, + basic_string_view<_CharT, _Traits> __y) noexcept + { return __x.size() == __y.size() && __x.compare(__y) == 0; } + + template<typename _CharT, typename _Traits> + /*constexpr*/ bool + operator==(basic_string_view<_CharT, _Traits> __x, + __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept + { return __x.size() == __y.size() && __x.compare(__y) == 0; } + + template<typename _CharT, typename _Traits> + /*constexpr*/ bool + operator==(__detail::__idt<basic_string_view<_CharT, _Traits>> __x, + basic_string_view<_CharT, _Traits> __y) noexcept + { return __x.size() == __y.size() && __x.compare(__y) == 0; } + + template<typename _CharT, typename _Traits> + /*constexpr*/ bool + operator!=(basic_string_view<_CharT, _Traits> __x, + basic_string_view<_CharT, _Traits> __y) noexcept + { return !(__x == __y); } + + template<typename _CharT, typename _Traits> + /*constexpr*/ bool + operator!=(basic_string_view<_CharT, _Traits> __x, + __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept + { return !(__x == __y); } + + template<typename _CharT, typename _Traits> + /*constexpr*/ bool + operator!=(__detail::__idt<basic_string_view<_CharT, _Traits>> __x, + basic_string_view<_CharT, _Traits> __y) noexcept + { return !(__x == __y); } + + template<typename _CharT, typename _Traits> + /*constexpr*/ bool + operator< (basic_string_view<_CharT, _Traits> __x, + basic_string_view<_CharT, _Traits> __y) noexcept + { return __x.compare(__y) < 0; } + + template<typename _CharT, typename _Traits> + /*constexpr*/ bool + operator< (basic_string_view<_CharT, _Traits> __x, + __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept + { return __x.compare(__y) < 0; } + + template<typename _CharT, typename _Traits> + /*constexpr*/ bool + operator< (__detail::__idt<basic_string_view<_CharT, _Traits>> __x, + basic_string_view<_CharT, _Traits> __y) noexcept + { return __x.compare(__y) < 0; } + + template<typename _CharT, typename _Traits> + /*constexpr*/ bool + operator> (basic_string_view<_CharT, _Traits> __x, + basic_string_view<_CharT, _Traits> __y) noexcept + { return __x.compare(__y) > 0; } + + template<typename _CharT, typename _Traits> + /*constexpr*/ bool + operator> (basic_string_view<_CharT, _Traits> __x, + __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept + { return __x.compare(__y) > 0; } + + template<typename _CharT, typename _Traits> + /*constexpr*/ bool + operator> (__detail::__idt<basic_string_view<_CharT, _Traits>> __x, + basic_string_view<_CharT, _Traits> __y) noexcept + { return __x.compare(__y) > 0; } + + template<typename _CharT, typename _Traits> + /*constexpr*/ bool + operator<=(basic_string_view<_CharT, _Traits> __x, + basic_string_view<_CharT, _Traits> __y) noexcept + { return __x.compare(__y) <= 0; } + + template<typename _CharT, typename _Traits> + /*constexpr*/ bool + operator<=(basic_string_view<_CharT, _Traits> __x, + __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept + { return __x.compare(__y) <= 0; } + + template<typename _CharT, typename _Traits> + /*constexpr*/ bool + operator<=(__detail::__idt<basic_string_view<_CharT, _Traits>> __x, + basic_string_view<_CharT, _Traits> __y) noexcept + { return __x.compare(__y) <= 0; } + + template<typename _CharT, typename _Traits> + /*constexpr*/ bool + operator>=(basic_string_view<_CharT, _Traits> __x, + basic_string_view<_CharT, _Traits> __y) noexcept + { return __x.compare(__y) >= 0; } + + template<typename _CharT, typename _Traits> + /*constexpr*/ bool + operator>=(basic_string_view<_CharT, _Traits> __x, + __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept + { return __x.compare(__y) >= 0; } + + template<typename _CharT, typename _Traits> + /*constexpr*/ bool + operator>=(__detail::__idt<basic_string_view<_CharT, _Traits>> __x, + basic_string_view<_CharT, _Traits> __y) noexcept + { return __x.compare(__y) >= 0; } + + // basic_string_view typedef names + + using string_view = basic_string_view<char>; +} /* namespace gdb */ + +#include "gdb_string_view.tcc" + +#endif // __cplusplus < 201703L + +#endif /* COMMON_GDB_STRING_VIEW_H */ diff --git a/gdbsupport/gdb_string_view.tcc b/gdbsupport/gdb_string_view.tcc new file mode 100644 index 0000000..ebf5907 --- /dev/null +++ b/gdbsupport/gdb_string_view.tcc @@ -0,0 +1,219 @@ +// Components for manipulating non-owning sequences of characters -*- C++ -*- + +// Note: This file has been stolen from the gcc repo +// (libstdc++-v3/include/experimental/bits/string_view.tcc) and has local +// modifications. + +// Copyright (C) 2013-2020 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file experimental/bits/string_view.tcc + * This is an internal header file, included by other library headers. + * Do not attempt to use it directly. @headername{experimental/string_view} + */ + +// +// N3762 basic_string_view library +// + +#ifndef GDB_STRING_VIEW_TCC +#define GDB_STRING_VIEW_TCC 1 + +namespace gdb +{ + template<typename _CharT, typename _Traits> + /*constexpr*/ typename basic_string_view<_CharT, _Traits>::size_type + basic_string_view<_CharT, _Traits>:: + find(const _CharT* __str, size_type __pos, size_type __n) const noexcept + { + gdb_assert (__str != nullptr || __n == 0); + + if (__n == 0) + return __pos <= this->_M_len ? __pos : npos; + + if (__n <= this->_M_len) + { + for (; __pos <= this->_M_len - __n; ++__pos) + if (traits_type::eq(this->_M_str[__pos], __str[0]) + && traits_type::compare(this->_M_str + __pos + 1, + __str + 1, __n - 1) == 0) + return __pos; + } + return npos; + } + + template<typename _CharT, typename _Traits> + /*constexpr*/ typename basic_string_view<_CharT, _Traits>::size_type + basic_string_view<_CharT, _Traits>:: + find(_CharT __c, size_type __pos) const noexcept + { + size_type __ret = npos; + if (__pos < this->_M_len) + { + const size_type __n = this->_M_len - __pos; + const _CharT* __p = traits_type::find(this->_M_str + __pos, __n, __c); + if (__p) + __ret = __p - this->_M_str; + } + return __ret; + } + + template<typename _CharT, typename _Traits> + /*constexpr*/ typename basic_string_view<_CharT, _Traits>::size_type + basic_string_view<_CharT, _Traits>:: + rfind(const _CharT* __str, size_type __pos, size_type __n) const noexcept + { + gdb_assert (__str != nullptr || __n == 0); + + if (__n <= this->_M_len) + { + __pos = std::min(size_type(this->_M_len - __n), __pos); + do + { + if (traits_type::compare(this->_M_str + __pos, __str, __n) == 0) + return __pos; + } + while (__pos-- > 0); + } + return npos; + } + + template<typename _CharT, typename _Traits> + /*constexpr*/ typename basic_string_view<_CharT, _Traits>::size_type + basic_string_view<_CharT, _Traits>:: + rfind(_CharT __c, size_type __pos) const noexcept + { + size_type __size = this->_M_len; + if (__size > 0) + { + if (--__size > __pos) + __size = __pos; + for (++__size; __size-- > 0; ) + if (traits_type::eq(this->_M_str[__size], __c)) + return __size; + } + return npos; + } + + template<typename _CharT, typename _Traits> + /*constexpr*/ typename basic_string_view<_CharT, _Traits>::size_type + basic_string_view<_CharT, _Traits>:: + find_first_of(const _CharT* __str, size_type __pos, size_type __n) const + { + gdb_assert (__str != nullptr || __n == 0); + for (; __n && __pos < this->_M_len; ++__pos) + { + const _CharT* __p = traits_type::find(__str, __n, + this->_M_str[__pos]); + if (__p) + return __pos; + } + return npos; + } + + template<typename _CharT, typename _Traits> + /*constexpr*/ typename basic_string_view<_CharT, _Traits>::size_type + basic_string_view<_CharT, _Traits>:: + find_last_of(const _CharT* __str, size_type __pos, size_type __n) const + { + gdb_assert (__str != nullptr || __n == 0); + size_type __size = this->size(); + if (__size && __n) + { + if (--__size > __pos) + __size = __pos; + do + { + if (traits_type::find(__str, __n, this->_M_str[__size])) + return __size; + } + while (__size-- != 0); + } + return npos; + } + + template<typename _CharT, typename _Traits> + /*constexpr*/ typename basic_string_view<_CharT, _Traits>::size_type + basic_string_view<_CharT, _Traits>:: + find_first_not_of(const _CharT* __str, size_type __pos, size_type __n) const + { + gdb_assert (__str != nullptr || __n == 0); + for (; __pos < this->_M_len; ++__pos) + if (!traits_type::find(__str, __n, this->_M_str[__pos])) + return __pos; + return npos; + } + + template<typename _CharT, typename _Traits> + /*constexpr*/ typename basic_string_view<_CharT, _Traits>::size_type + basic_string_view<_CharT, _Traits>:: + find_first_not_of(_CharT __c, size_type __pos) const noexcept + { + for (; __pos < this->_M_len; ++__pos) + if (!traits_type::eq(this->_M_str[__pos], __c)) + return __pos; + return npos; + } + + template<typename _CharT, typename _Traits> + /*constexpr*/ typename basic_string_view<_CharT, _Traits>::size_type + basic_string_view<_CharT, _Traits>:: + find_last_not_of(const _CharT* __str, size_type __pos, size_type __n) const + { + gdb_assert (__str != nullptr || __n == 0); + size_type __size = this->_M_len; + if (__size) + { + if (--__size > __pos) + __size = __pos; + do + { + if (!traits_type::find(__str, __n, this->_M_str[__size])) + return __size; + } + while (__size--); + } + return npos; + } + + template<typename _CharT, typename _Traits> + /*constexpr*/ typename basic_string_view<_CharT, _Traits>::size_type + basic_string_view<_CharT, _Traits>:: + find_last_not_of(_CharT __c, size_type __pos) const noexcept + { + size_type __size = this->_M_len; + if (__size) + { + if (--__size > __pos) + __size = __pos; + do + { + if (!traits_type::eq(this->_M_str[__size], __c)) + return __size; + } + while (__size--); + } + return npos; + } +} // namespace gdb + +#endif // GDB_STRING_VIEW_TCC diff --git a/gdbsupport/gdb_sys_time.h b/gdbsupport/gdb_sys_time.h new file mode 100644 index 0000000..b3b0cbe --- /dev/null +++ b/gdbsupport/gdb_sys_time.h @@ -0,0 +1,38 @@ +/* Copyright (C) 2015-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_GDB_SYS_TIME_H +#define COMMON_GDB_SYS_TIME_H + +#include <sys/time.h> + +/* On MinGW-w64, gnulib's sys/time.h replaces 'struct timeval' and + gettimeofday with versions that support 64-bit time_t, for POSIX + compliance. However, the gettimeofday replacement does not ever + return time_t values larger than 31-bit, as it simply returns the + system's gettimeofday's (signed) 32-bit result as (signed) 64-bit. + Because we don't really need the POSIX compliance, and it ends up + causing conflicts with other libraries we use that don't use gnulib + and thus work with the native struct timeval, such as Winsock2's + native 'select' and libiberty, simply undefine away gnulib's + replacements. */ +#if GNULIB_defined_struct_timeval +# undef timeval +# undef gettimeofday +#endif + +#endif /* COMMON_GDB_SYS_TIME_H */ diff --git a/gdbsupport/gdb_tilde_expand.c b/gdbsupport/gdb_tilde_expand.c new file mode 100644 index 0000000..6671629 --- /dev/null +++ b/gdbsupport/gdb_tilde_expand.c @@ -0,0 +1,95 @@ +/* Perform tilde expansion on paths for GDB and gdbserver. + + Copyright (C) 2017-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "common-defs.h" +#include "gdb_tilde_expand.h" +#include <glob.h> + +/* RAII-style class wrapping "glob". */ + +class gdb_glob +{ +public: + /* Construct a "gdb_glob" object by calling "glob" with the provided + parameters. This function can throw if "glob" fails. */ + gdb_glob (const char *pattern, int flags, + int (*errfunc) (const char *epath, int eerrno)) + { + int ret = glob (pattern, flags, errfunc, &m_glob); + + if (ret != 0) + { + if (ret == GLOB_NOMATCH) + error (_("Could not find a match for '%s'."), pattern); + else + error (_("glob could not process pattern '%s'."), + pattern); + } + } + + /* Destroy the object and free M_GLOB. */ + ~gdb_glob () + { + globfree (&m_glob); + } + + /* Return the GL_PATHC component of M_GLOB. */ + int pathc () const + { + return m_glob.gl_pathc; + } + + /* Return the GL_PATHV component of M_GLOB. */ + char **pathv () const + { + return m_glob.gl_pathv; + } + +private: + /* The actual glob object we're dealing with. */ + glob_t m_glob; +}; + +/* See gdbsupport/gdb_tilde_expand.h. */ + +std::string +gdb_tilde_expand (const char *dir) +{ + gdb_glob glob (dir, GLOB_TILDE_CHECK, NULL); + + gdb_assert (glob.pathc () > 0); + /* "glob" may return more than one match to the path provided by the + user, but we are only interested in the first match. */ + std::string expanded_dir = glob.pathv ()[0]; + + return expanded_dir; +} + +/* See gdbsupport/gdb_tilde_expand.h. */ + +gdb::unique_xmalloc_ptr<char> +gdb_tilde_expand_up (const char *dir) +{ + gdb_glob glob (dir, GLOB_TILDE_CHECK, NULL); + + gdb_assert (glob.pathc () > 0); + /* "glob" may return more than one match to the path provided by the + user, but we are only interested in the first match. */ + return make_unique_xstrdup (glob.pathv ()[0]); +} diff --git a/gdbsupport/gdb_tilde_expand.h b/gdbsupport/gdb_tilde_expand.h new file mode 100644 index 0000000..5f4ef60 --- /dev/null +++ b/gdbsupport/gdb_tilde_expand.h @@ -0,0 +1,31 @@ +/* Perform tilde expansion on paths for GDB and gdbserver. + + Copyright (C) 2017-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_GDB_TILDE_EXPAND_H +#define COMMON_GDB_TILDE_EXPAND_H + +/* Perform path expansion (i.e., tilde expansion) on DIR, and return + the full path. */ +extern std::string gdb_tilde_expand (const char *dir); + +/* Same as GDB_TILDE_EXPAND, but return the full path as a + gdb::unique_xmalloc_ptr<char>. */ +extern gdb::unique_xmalloc_ptr<char> gdb_tilde_expand_up (const char *dir); + +#endif /* COMMON_GDB_TILDE_EXPAND_H */ diff --git a/gdbsupport/gdb_unique_ptr.h b/gdbsupport/gdb_unique_ptr.h new file mode 100644 index 0000000..5e383b9 --- /dev/null +++ b/gdbsupport/gdb_unique_ptr.h @@ -0,0 +1,67 @@ +/* std::unique_ptr specializations for GDB. + + Copyright (C) 2016-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_GDB_UNIQUE_PTR_H +#define COMMON_GDB_UNIQUE_PTR_H + +#include <memory> + +namespace gdb +{ +/* Define gdb::unique_xmalloc_ptr, a std::unique_ptr that manages + xmalloc'ed memory. */ + +/* The deleter for std::unique_xmalloc_ptr. Uses xfree. */ +template <typename T> +struct xfree_deleter +{ + void operator() (T *ptr) const { xfree (ptr); } +}; + +/* Same, for arrays. */ +template <typename T> +struct xfree_deleter<T[]> +{ + void operator() (T *ptr) const { xfree (ptr); } +}; + +/* Import the standard unique_ptr to our namespace with a custom + deleter. */ + +template<typename T> using unique_xmalloc_ptr + = std::unique_ptr<T, xfree_deleter<T>>; + +/* A no-op deleter. */ +template<typename T> +struct noop_deleter +{ + void operator() (T *ptr) const { } +}; + +} /* namespace gdb */ + +/* Dup STR and return a unique_xmalloc_ptr for the result. */ + +static inline gdb::unique_xmalloc_ptr<char> +make_unique_xstrdup (const char *str) +{ + return gdb::unique_xmalloc_ptr<char> (xstrdup (str)); +} + +#endif /* COMMON_GDB_UNIQUE_PTR_H */ diff --git a/gdbsupport/gdb_unlinker.h b/gdbsupport/gdb_unlinker.h new file mode 100644 index 0000000..9d64cca --- /dev/null +++ b/gdbsupport/gdb_unlinker.h @@ -0,0 +1,60 @@ +/* Unlinking class + + Copyright (C) 2016-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_GDB_UNLINKER_H +#define COMMON_GDB_UNLINKER_H + +namespace gdb +{ + +/* An object of this class holds a filename and, when the object goes + of scope, the file is removed using unlink. + + A user of this class can request that the file be preserved using + the "keep" method. */ +class unlinker +{ + public: + + unlinker (const char *filename) ATTRIBUTE_NONNULL (2) + : m_filename (filename) + { + gdb_assert (filename != NULL); + } + + ~unlinker () + { + if (m_filename != NULL) + unlink (m_filename); + } + + /* Keep the file, rather than unlink it. */ + void keep () + { + m_filename = NULL; + } + + private: + + const char *m_filename; +}; + +} + +#endif /* COMMON_GDB_UNLINKER_H */ diff --git a/gdbsupport/gdb_vecs.c b/gdbsupport/gdb_vecs.c new file mode 100644 index 0000000..bb81396 --- /dev/null +++ b/gdbsupport/gdb_vecs.c @@ -0,0 +1,88 @@ +/* Some commonly-used VEC types. + + Copyright (C) 2012-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "common-defs.h" +#include "gdb_vecs.h" +#include "host-defs.h" + +/* Worker function to split character delimiter separated string of fields + STR into a char pointer vector. */ + +static void +delim_string_to_char_ptr_vec_append + (std::vector<gdb::unique_xmalloc_ptr<char>> *vecp, const char *str, + char delimiter) +{ + do + { + size_t this_len; + const char *next_field; + char *this_field; + + next_field = strchr (str, delimiter); + if (next_field == NULL) + this_len = strlen (str); + else + { + this_len = next_field - str; + next_field++; + } + + this_field = (char *) xmalloc (this_len + 1); + memcpy (this_field, str, this_len); + this_field[this_len] = '\0'; + vecp->emplace_back (this_field); + + str = next_field; + } + while (str != NULL); +} + +/* See gdb_vecs.h. */ + +std::vector<gdb::unique_xmalloc_ptr<char>> +delim_string_to_char_ptr_vec (const char *str, char delimiter) +{ + std::vector<gdb::unique_xmalloc_ptr<char>> retval; + + delim_string_to_char_ptr_vec_append (&retval, str, delimiter); + + return retval; +} + +/* See gdb_vecs.h. */ + +void +dirnames_to_char_ptr_vec_append + (std::vector<gdb::unique_xmalloc_ptr<char>> *vecp, const char *dirnames) +{ + delim_string_to_char_ptr_vec_append (vecp, dirnames, DIRNAME_SEPARATOR); +} + +/* See gdb_vecs.h. */ + +std::vector<gdb::unique_xmalloc_ptr<char>> +dirnames_to_char_ptr_vec (const char *dirnames) +{ + std::vector<gdb::unique_xmalloc_ptr<char>> retval; + + dirnames_to_char_ptr_vec_append (&retval, dirnames); + + return retval; +} diff --git a/gdbsupport/gdb_vecs.h b/gdbsupport/gdb_vecs.h new file mode 100644 index 0000000..ca7097a --- /dev/null +++ b/gdbsupport/gdb_vecs.h @@ -0,0 +1,88 @@ +/* Some commonly-used VEC types. + + Copyright (C) 2012-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_GDB_VECS_H +#define COMMON_GDB_VECS_H + +/* Split STR, a list of DELIMITER-separated fields, into a char pointer vector. + + You may modify the returned strings. */ + +extern std::vector<gdb::unique_xmalloc_ptr<char>> + delim_string_to_char_ptr_vec (const char *str, char delimiter); + +/* Like dirnames_to_char_ptr_vec, but append the directories to *VECP. */ + +extern void dirnames_to_char_ptr_vec_append + (std::vector<gdb::unique_xmalloc_ptr<char>> *vecp, const char *dirnames); + +/* Split DIRNAMES by DIRNAME_SEPARATOR delimiter and return a list of all the + elements in their original order. For empty string ("") DIRNAMES return + list of one empty string ("") element. + + You may modify the returned strings. */ + +extern std::vector<gdb::unique_xmalloc_ptr<char>> + dirnames_to_char_ptr_vec (const char *dirnames); + +/* Remove the element pointed by iterator IT from VEC, not preserving the order + of the remaining elements. Return the removed element. */ + +template <typename T> +T +unordered_remove (std::vector<T> &vec, typename std::vector<T>::iterator it) +{ + gdb_assert (it >= vec.begin () && it < vec.end ()); + + T removed = std::move (*it); + if (it != vec.end () - 1) + *it = std::move (vec.back ()); + vec.pop_back (); + + return removed; +} + +/* Remove the element at position IX from VEC, not preserving the order of the + remaining elements. Return the removed element. */ + +template <typename T> +T +unordered_remove (std::vector<T> &vec, typename std::vector<T>::size_type ix) +{ + gdb_assert (ix < vec.size ()); + + return unordered_remove (vec, vec.begin () + ix); +} + +/* Remove the element at position IX from VEC, preserving the order the + remaining elements. Return the removed element. */ + +template <typename T> +T +ordered_remove (std::vector<T> &vec, typename std::vector<T>::size_type ix) +{ + gdb_assert (ix < vec.size ()); + + T removed = std::move (vec[ix]); + vec.erase (vec.begin () + ix); + + return removed; +} + +#endif /* COMMON_GDB_VECS_H */ diff --git a/gdbsupport/gdb_wait.c b/gdbsupport/gdb_wait.c new file mode 100644 index 0000000..3213994 --- /dev/null +++ b/gdbsupport/gdb_wait.c @@ -0,0 +1,85 @@ +/* Support code for standard wait macros in gdb_wait.h. + + Copyright (C) 2019 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "common-defs.h" + +#include "gdb_wait.h" + +#ifdef __MINGW32__ + +/* The underlying idea is that when a Windows program is terminated by + a fatal exception, its exit code is the value of that exception, as + defined by the various EXCEPTION_* symbols in the Windows API + headers. We thus emulate WTERMSIG etc. by translating the fatal + exception codes to more-or-less equivalent Posix signals. + + The translation below is not perfect, because a program could + legitimately exit normally with a status whose value happens to + have the high bits set, but that's extremely rare, to say the + least, and it is deemed such a negligibly small probability of + false positives is justified by the utility of reporting the + terminating signal in the "normal" cases. */ + +# include <signal.h> + +# define WIN32_LEAN_AND_MEAN +# include <windows.h> /* for EXCEPTION_* constants */ + +struct xlate_status +{ + /* The exit status (actually, fatal exception code). */ + DWORD status; + + /* The corresponding signal value. */ + int sig; +}; + +int +windows_status_to_termsig (unsigned long status) +{ + static const xlate_status status_xlate_tbl[] = + { + {EXCEPTION_ACCESS_VIOLATION, SIGSEGV}, + {EXCEPTION_IN_PAGE_ERROR, SIGSEGV}, + {EXCEPTION_INVALID_HANDLE, SIGSEGV}, + {EXCEPTION_ILLEGAL_INSTRUCTION, SIGILL}, + {EXCEPTION_NONCONTINUABLE_EXCEPTION, SIGILL}, + {EXCEPTION_ARRAY_BOUNDS_EXCEEDED, SIGSEGV}, + {EXCEPTION_FLT_DENORMAL_OPERAND, SIGFPE}, + {EXCEPTION_FLT_DIVIDE_BY_ZERO, SIGFPE}, + {EXCEPTION_FLT_INEXACT_RESULT, SIGFPE}, + {EXCEPTION_FLT_INVALID_OPERATION, SIGFPE}, + {EXCEPTION_FLT_OVERFLOW, SIGFPE}, + {EXCEPTION_FLT_STACK_CHECK, SIGFPE}, + {EXCEPTION_FLT_UNDERFLOW, SIGFPE}, + {EXCEPTION_INT_DIVIDE_BY_ZERO, SIGFPE}, + {EXCEPTION_INT_OVERFLOW, SIGFPE}, + {EXCEPTION_PRIV_INSTRUCTION, SIGILL}, + {EXCEPTION_STACK_OVERFLOW, SIGSEGV}, + {CONTROL_C_EXIT, SIGTERM} + }; + + for (const xlate_status &x : status_xlate_tbl) + if (x.status == status) + return x.sig; + + return -1; +} + +#endif /* __MINGW32__ */ diff --git a/gdbsupport/gdb_wait.h b/gdbsupport/gdb_wait.h new file mode 100644 index 0000000..3563b9c --- /dev/null +++ b/gdbsupport/gdb_wait.h @@ -0,0 +1,135 @@ +/* Standard wait macros. + Copyright (C) 2000-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_GDB_WAIT_H +#define COMMON_GDB_WAIT_H + +#ifdef HAVE_SYS_WAIT_H +#include <sys/wait.h> /* POSIX */ +#else +#ifdef HAVE_WAIT_H +#include <wait.h> /* legacy */ +#endif +#endif + +/* Define how to access the int that the wait system call stores. + This has been compatible in all Unix systems since time immemorial, + but various well-meaning people have defined various different + words for the same old bits in the same old int (sometimes claimed + to be a struct). We just know it's an int and we use these macros + to access the bits. */ + +/* The following macros are defined equivalently to their definitions + in POSIX.1. We fail to define WNOHANG and WUNTRACED, which POSIX.1 + <sys/wait.h> defines, since our code does not use waitpid() (but + NOTE exception for GNU/Linux below). We also fail to declare + wait() and waitpid(). + + For MinGW, we use the fact that when a Windows program is + terminated by a fatal exception, its exit code is the value of that + exception, as defined by the various EXCEPTION_* symbols in the + Windows API headers. See also gdb_wait.c. */ + +#ifndef WIFEXITED +# ifdef __MINGW32__ +# define WIFEXITED(w) (((w) & 0xC0000000) == 0) +# else +# define WIFEXITED(w) (((w)&0377) == 0) +# endif +#endif + +#ifndef WIFSIGNALED +# ifdef __MINGW32__ +# define WIFSIGNALED(w) (((w) & 0xC0000000) == 0xC0000000) +# else +# define WIFSIGNALED(w) (((w)&0377) != 0177 && ((w)&~0377) == 0) +# endif +#endif + +#ifndef WIFSTOPPED +#ifdef IBM6000 + +/* Unfortunately, the above comment (about being compatible in all Unix + systems) is not quite correct for AIX, sigh. And AIX 3.2 can generate + status words like 0x57c (sigtrap received after load), and gdb would + choke on it. */ + +#define WIFSTOPPED(w) ((w)&0x40) + +#else +#define WIFSTOPPED(w) (((w)&0377) == 0177) +#endif +#endif + +#ifndef WEXITSTATUS +# ifdef __MINGW32__ +# define WEXITSTATUS(w) ((w) & ~0xC0000000) +# else +# define WEXITSTATUS(w) (((w) >> 8) & 0377) /* same as WRETCODE */ +# endif +#endif + +#ifndef WTERMSIG +# ifdef __MINGW32__ +extern int windows_status_to_termsig (unsigned long); +# define WTERMSIG(w) windows_status_to_termsig (w) +# else +# define WTERMSIG(w) ((w) & 0177) +# endif +#endif + +#ifndef WSTOPSIG +#define WSTOPSIG WEXITSTATUS +#endif + +/* These are not defined in POSIX, but are used by our programs. */ + +#ifndef WSETEXIT +# ifdef W_EXITCODE +#define WSETEXIT(w,status) ((w) = W_EXITCODE(status,0)) +# else +#define WSETEXIT(w,status) ((w) = (0 | ((status) << 8))) +# endif +#endif + +#ifndef W_STOPCODE +#define W_STOPCODE(sig) ((sig) << 8 | 0x7f) +#endif + +#ifndef WSETSTOP +#define WSETSTOP(w,sig) ((w) = W_STOPCODE(sig)) +#endif + +/* For native GNU/Linux we may use waitpid and the __WCLONE option. + <GRIPE> It is of course dangerous not to use the REAL header file... + </GRIPE>. */ + +/* Bits in the third argument to `waitpid'. */ +#ifndef WNOHANG +#define WNOHANG 1 /* Don't block waiting. */ +#endif + +#ifndef WUNTRACED +#define WUNTRACED 2 /* Report status of stopped children. */ +#endif + +#ifndef __WCLONE +#define __WCLONE 0x80000000 /* Wait for cloned process. */ +#endif + +#endif /* COMMON_GDB_WAIT_H */ diff --git a/gdbsupport/hash_enum.h b/gdbsupport/hash_enum.h new file mode 100644 index 0000000..a6c519a --- /dev/null +++ b/gdbsupport/hash_enum.h @@ -0,0 +1,45 @@ +/* A hasher for enums. + + Copyright (C) 2017-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_HASH_ENUM_H +#define COMMON_HASH_ENUM_H + +/* A hasher for enums, which was missing in C++11: + http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2148 +*/ + +namespace gdb { + +/* Helper struct for hashing enum types. */ +template<typename T> +struct hash_enum +{ + typedef size_t result_type; + typedef T argument_type; + + size_t operator() (T val) const noexcept + { + using underlying = typename std::underlying_type<T>::type; + return std::hash<underlying> () (static_cast<underlying> (val)); + } +}; + +} /* namespace gdb */ + +#endif /* COMMON_HASH_ENUM_H */ diff --git a/gdbsupport/host-defs.h b/gdbsupport/host-defs.h new file mode 100644 index 0000000..925a497 --- /dev/null +++ b/gdbsupport/host-defs.h @@ -0,0 +1,61 @@ +/* Basic host-specific definitions for GDB. + Copyright (C) 1986-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_HOST_DEFS_H +#define COMMON_HOST_DEFS_H + +#include <limits.h> + +/* Static host-system-dependent parameters for GDB. */ + +/* * Number of bits in a char or unsigned char for the target machine. + Just like CHAR_BIT in <limits.h> but describes the target machine. */ +#if !defined (TARGET_CHAR_BIT) +#define TARGET_CHAR_BIT 8 +#endif + +/* * If we picked up a copy of CHAR_BIT from a configuration file + (which may get it by including <limits.h>) then use it to set + the number of bits in a host char. If not, use the same size + as the target. */ + +#if defined (CHAR_BIT) +#define HOST_CHAR_BIT CHAR_BIT +#else +#define HOST_CHAR_BIT TARGET_CHAR_BIT +#endif + +#ifdef __MSDOS__ +# define CANT_FORK +# define GLOBAL_CURDIR +# define DIRNAME_SEPARATOR ';' +#endif + +#if !defined (__CYGWIN__) && defined (_WIN32) +# define DIRNAME_SEPARATOR ';' +#endif + +#ifndef DIRNAME_SEPARATOR +#define DIRNAME_SEPARATOR ':' +#endif + +#ifndef SLASH_STRING +#define SLASH_STRING "/" +#endif + +#endif /* COMMON_HOST_DEFS_H */ diff --git a/gdbsupport/job-control.c b/gdbsupport/job-control.c new file mode 100644 index 0000000..381c5f0 --- /dev/null +++ b/gdbsupport/job-control.c @@ -0,0 +1,86 @@ +/* Job control and terminal related functions, for GDB and gdbserver + when running under Unix. + + Copyright (C) 1986-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "common-defs.h" +#include "job-control.h" +#ifdef HAVE_TERMIOS_H +#include <termios.h> +#endif +#include <unistd.h> + +/* Nonzero if we have job control. */ +int job_control; + +/* Set the process group ID of the inferior. + + Just using job_control only does part of it because setpgid or + setpgrp might not exist on a system without job control. + + For a more clean implementation, in libiberty, put a setpgid which merely + calls setpgrp and a setpgrp which does nothing (any system with job control + will have one or the other). */ + +int +gdb_setpgid () +{ + int retval = 0; + + if (job_control) + { +#ifdef HAVE_SETPGID + /* The call setpgid (0, 0) is supposed to work and mean the same + thing as this, but on Ultrix 4.2A it fails with EPERM (and + setpgid (getpid (), getpid ()) succeeds). */ + retval = setpgid (getpid (), getpid ()); +#else +#ifdef HAVE_SETPGRP +#ifdef SETPGRP_VOID + retval = setpgrp (); +#else + retval = setpgrp (getpid (), getpid ()); +#endif +#endif /* HAVE_SETPGRP */ +#endif /* HAVE_SETPGID */ + } + + return retval; +} + +/* See gdbsupport/common-terminal.h. */ + +void +have_job_control () +{ + /* OK, figure out whether we have job control. If termios is not + available, leave job_control 0. */ +#if defined (HAVE_TERMIOS_H) + /* Do all systems with termios have the POSIX way of identifying job + control? I hope so. */ +#ifdef _POSIX_JOB_CONTROL + job_control = 1; +#else +#ifdef _SC_JOB_CONTROL + job_control = sysconf (_SC_JOB_CONTROL); +#else + job_control = 0; /* Have to assume the worst. */ +#endif /* _SC_JOB_CONTROL */ +#endif /* _POSIX_JOB_CONTROL */ +#endif /* HAVE_TERMIOS_H */ +} diff --git a/gdbsupport/job-control.h b/gdbsupport/job-control.h new file mode 100644 index 0000000..23e503d --- /dev/null +++ b/gdbsupport/job-control.h @@ -0,0 +1,38 @@ +/* Job control and terminal related functions, for GDB and gdbserver + when running under Unix. + + Copyright (C) 1986-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_JOB_CONTROL_H +#define COMMON_JOB_CONTROL_H + +/* Do we have job control? Can be assumed to always be the same + within a given run of GDB. Use in gdb/inflow.c and + gdbsupport/common-inflow.c. */ +extern int job_control; + +/* Set the process group of the caller to its own pid, or do nothing + if we lack job control. */ +extern int gdb_setpgid (); + +/* Determine whether we have job control, and set variable JOB_CONTROL + accordingly. This function must be called before any use of + JOB_CONTROL. */ +extern void have_job_control (); + +#endif /* COMMON_JOB_CONTROL_H */ diff --git a/gdbsupport/netstuff.c b/gdbsupport/netstuff.c new file mode 100644 index 0000000..1bf8f4b --- /dev/null +++ b/gdbsupport/netstuff.c @@ -0,0 +1,154 @@ +/* Operations on network stuff. + Copyright (C) 2018-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "common-defs.h" +#include "netstuff.h" +#include <algorithm> + +#ifdef USE_WIN32API +#include <ws2tcpip.h> +#else +#include <netinet/in.h> +#include <arpa/inet.h> +#include <netdb.h> +#include <sys/socket.h> +#include <netinet/tcp.h> +#endif + +/* See gdbsupport/netstuff.h. */ + +scoped_free_addrinfo::~scoped_free_addrinfo () +{ + freeaddrinfo (m_res); +} + +/* See gdbsupport/netstuff.h. */ + +parsed_connection_spec +parse_connection_spec_without_prefix (std::string spec, struct addrinfo *hint) +{ + parsed_connection_spec ret; + size_t last_colon_pos = 0; + /* We're dealing with IPv6 if: + + - ai_family is AF_INET6, or + - ai_family is not AF_INET, and + - spec[0] is '[', or + - the number of ':' on spec is greater than 1. */ + bool is_ipv6 = (hint->ai_family == AF_INET6 + || (hint->ai_family != AF_INET + && (spec[0] == '[' + || std::count (spec.begin (), + spec.end (), ':') > 1))); + + if (is_ipv6) + { + if (spec[0] == '[') + { + /* IPv6 addresses can be written as '[ADDR]:PORT', and we + support this notation. */ + size_t close_bracket_pos = spec.find_first_of (']'); + + if (close_bracket_pos == std::string::npos) + error (_("Missing close bracket in hostname '%s'"), + spec.c_str ()); + + hint->ai_family = AF_INET6; + + const char c = spec[close_bracket_pos + 1]; + + if (c == '\0') + last_colon_pos = std::string::npos; + else if (c != ':') + error (_("Invalid cruft after close bracket in '%s'"), + spec.c_str ()); + + /* Erase both '[' and ']'. */ + spec.erase (0, 1); + spec.erase (close_bracket_pos - 1, 1); + } + else if (spec.find_first_of (']') != std::string::npos) + error (_("Missing open bracket in hostname '%s'"), + spec.c_str ()); + } + + if (last_colon_pos == 0) + last_colon_pos = spec.find_last_of (':'); + + /* The length of the hostname part. */ + size_t host_len; + + if (last_colon_pos != std::string::npos) + { + /* The user has provided a port. */ + host_len = last_colon_pos; + ret.port_str = spec.substr (last_colon_pos + 1); + } + else + host_len = spec.size (); + + ret.host_str = spec.substr (0, host_len); + + /* Default hostname is localhost. */ + if (ret.host_str.empty ()) + ret.host_str = "localhost"; + + return ret; +} + +/* See gdbsupport/netstuff.h. */ + +parsed_connection_spec +parse_connection_spec (const char *spec, struct addrinfo *hint) +{ + /* Struct to hold the association between valid prefixes, their + family and socktype. */ + struct host_prefix + { + /* The prefix. */ + const char *prefix; + + /* The 'ai_family'. */ + int family; + + /* The 'ai_socktype'. */ + int socktype; + }; + static const struct host_prefix prefixes[] = + { + { "udp:", AF_UNSPEC, SOCK_DGRAM }, + { "tcp:", AF_UNSPEC, SOCK_STREAM }, + { "udp4:", AF_INET, SOCK_DGRAM }, + { "tcp4:", AF_INET, SOCK_STREAM }, + { "udp6:", AF_INET6, SOCK_DGRAM }, + { "tcp6:", AF_INET6, SOCK_STREAM }, + }; + + for (const host_prefix prefix : prefixes) + if (startswith (spec, prefix.prefix)) + { + spec += strlen (prefix.prefix); + hint->ai_family = prefix.family; + hint->ai_socktype = prefix.socktype; + hint->ai_protocol + = hint->ai_socktype == SOCK_DGRAM ? IPPROTO_UDP : IPPROTO_TCP; + break; + } + + return parse_connection_spec_without_prefix (spec, hint); +} diff --git a/gdbsupport/netstuff.h b/gdbsupport/netstuff.h new file mode 100644 index 0000000..a987d7f --- /dev/null +++ b/gdbsupport/netstuff.h @@ -0,0 +1,76 @@ +/* Operations on network stuff. + Copyright (C) 2018-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_NETSTUFF_H +#define COMMON_NETSTUFF_H + +#include <string> + +/* Like NI_MAXHOST/NI_MAXSERV, but enough for numeric forms. */ +#define GDB_NI_MAX_ADDR 64 +#define GDB_NI_MAX_PORT 16 + +/* Helper class to guarantee that we always call 'freeaddrinfo'. */ + +class scoped_free_addrinfo +{ +public: + /* Default constructor. */ + explicit scoped_free_addrinfo (struct addrinfo *ainfo) + : m_res (ainfo) + { + } + + /* Destructor responsible for free'ing M_RES by calling + 'freeaddrinfo'. */ + ~scoped_free_addrinfo (); + + DISABLE_COPY_AND_ASSIGN (scoped_free_addrinfo); + +private: + /* The addrinfo resource. */ + struct addrinfo *m_res; +}; + +/* The struct we return after parsing the connection spec. */ + +struct parsed_connection_spec +{ + /* The hostname. */ + std::string host_str; + + /* The port, if any. */ + std::string port_str; +}; + + +/* Parse SPEC (which is a string in the form of "ADDR:PORT") and + return a 'parsed_connection_spec' structure with the proper fields + filled in. Also adjust HINT accordingly. */ +extern parsed_connection_spec + parse_connection_spec_without_prefix (std::string spec, + struct addrinfo *hint); + +/* Parse SPEC (which is a string in the form of + "[tcp[6]:|udp[6]:]ADDR:PORT") and return a 'parsed_connection_spec' + structure with the proper fields filled in. Also adjust HINT + accordingly. */ +extern parsed_connection_spec parse_connection_spec (const char *spec, + struct addrinfo *hint); + +#endif /* COMMON_NETSTUFF_H */ diff --git a/gdbsupport/new-op.c b/gdbsupport/new-op.c new file mode 100644 index 0000000..cf2525c --- /dev/null +++ b/gdbsupport/new-op.c @@ -0,0 +1,95 @@ +/* Replace operator new/new[], for GDB, the GNU debugger. + + Copyright (C) 2016-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +/* GCC does not understand __has_feature. */ +#if !defined(__has_feature) +# define __has_feature(x) 0 +#endif + +#if !__has_feature(address_sanitizer) && !defined(__SANITIZE_ADDRESS__) +#include "common-defs.h" +#include "host-defs.h" +#include <new> + +/* Override operator new / operator new[], in order to internal_error + on allocation failure and thus query the user for abort/core + dump/continue, just like xmalloc does. We don't do this from a + new-handler function instead (std::set_new_handler) because we want + to catch allocation errors from within global constructors too. + + Skip overriding if building with -fsanitize=address though. + Address sanitizer wants to override operator new/delete too in + order to detect malloc+delete and new+free mismatches. Our + versions would mask out ASan's, with the result of losing that + useful mismatch detection. + + Note that C++ implementations could either have their throw + versions call the nothrow versions (libstdc++), or the other way + around (clang/libc++). For that reason, we replace both throw and + nothrow variants and call malloc directly. */ + +void * +operator new (std::size_t sz) +{ + /* malloc (0) is unpredictable; avoid it. */ + if (sz == 0) + sz = 1; + + void *p = malloc (sz); /* ARI: malloc */ + if (p == NULL) + { + /* If the user decides to continue debugging, throw a + gdb_quit_bad_alloc exception instead of a regular QUIT + gdb_exception. The former extends both std::bad_alloc and a + QUIT gdb_exception. This is necessary because operator new + can only ever throw std::bad_alloc, or something that extends + it. */ + try + { + malloc_failure (sz); + } + catch (gdb_exception &ex) + { + throw gdb_quit_bad_alloc (std::move (ex)); + } + } + return p; +} + +void * +operator new (std::size_t sz, const std::nothrow_t&) noexcept +{ + /* malloc (0) is unpredictable; avoid it. */ + if (sz == 0) + sz = 1; + return malloc (sz); /* ARI: malloc */ +} + +void * +operator new[] (std::size_t sz) +{ + return ::operator new (sz); +} + +void* +operator new[] (std::size_t sz, const std::nothrow_t&) noexcept +{ + return ::operator new (sz, std::nothrow); +} +#endif diff --git a/gdbsupport/next-iterator.h b/gdbsupport/next-iterator.h new file mode 100644 index 0000000..ad37412 --- /dev/null +++ b/gdbsupport/next-iterator.h @@ -0,0 +1,102 @@ +/* A "next" iterator for GDB, the GNU debugger. + Copyright (C) 2019-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_NEXT_ITERATOR_H +#define COMMON_NEXT_ITERATOR_H + +/* An iterator that uses the 'next' field of a type to iterate. This + can be used with various GDB types that are stored as linked + lists. */ + +template<typename T> +struct next_iterator +{ + typedef next_iterator self_type; + typedef T *value_type; + typedef T *&reference; + typedef T **pointer; + typedef std::forward_iterator_tag iterator_category; + typedef int difference_type; + + explicit next_iterator (T *item) + : m_item (item) + { + } + + /* Create a one-past-the-end iterator. */ + next_iterator () + : m_item (nullptr) + { + } + + value_type operator* () const + { + return m_item; + } + + bool operator== (const self_type &other) const + { + return m_item == other.m_item; + } + + bool operator!= (const self_type &other) const + { + return m_item != other.m_item; + } + + self_type &operator++ () + { + m_item = m_item->next; + return *this; + } + +private: + + T *m_item; +}; + +/* A range adapter that allows iterating over a linked list. */ + +template<typename T, typename Iterator = next_iterator<T>> +class next_adapter +{ +public: + + explicit next_adapter (T *item) + : m_item (item) + { + } + + using iterator = Iterator; + + iterator begin () const + { + return iterator (m_item); + } + + iterator end () const + { + return iterator (); + } + +private: + + T *m_item; +}; + +#endif /* COMMON_NEXT_ITERATOR_H */ diff --git a/gdbsupport/observable.h b/gdbsupport/observable.h new file mode 100644 index 0000000..0468eba --- /dev/null +++ b/gdbsupport/observable.h @@ -0,0 +1,119 @@ +/* Observers + + Copyright (C) 2016-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_OBSERVABLE_H +#define COMMON_OBSERVABLE_H + +#include <algorithm> +#include <functional> +#include <vector> + +namespace gdb +{ + +namespace observers +{ + +extern unsigned int observer_debug; + +/* An observer is an entity which is interested in being notified + when GDB reaches certain states, or certain events occur in GDB. + The entity being observed is called the observable. To receive + notifications, the observer attaches a callback to the observable. + One observable can have several observers. + + The observer implementation is also currently not reentrant. In + particular, it is therefore not possible to call the attach or + detach routines during a notification. */ + +/* The type of a key that can be passed to attach, which can be passed + to detach to remove associated observers. Tokens have address + identity, and are thus usually const globals. */ +struct token +{ + token () = default; + + DISABLE_COPY_AND_ASSIGN (token); +}; + +template<typename... T> +class observable +{ +public: + + typedef std::function<void (T...)> func_type; + + explicit observable (const char *name) + : m_name (name) + { + } + + DISABLE_COPY_AND_ASSIGN (observable); + + /* Attach F as an observer to this observable. F cannot be + detached. */ + void attach (const func_type &f) + { + m_observers.emplace_back (nullptr, f); + } + + /* Attach F as an observer to this observable. T is a reference to + a token that can be used to later remove F. */ + void attach (const func_type &f, const token &t) + { + m_observers.emplace_back (&t, f); + } + + /* Remove observers associated with T from this observable. T is + the token that was previously passed to any number of "attach" + calls. */ + void detach (const token &t) + { + auto iter = std::remove_if (m_observers.begin (), + m_observers.end (), + [&] (const std::pair<const token *, + func_type> &e) + { + return e.first == &t; + }); + + m_observers.erase (iter, m_observers.end ()); + } + + /* Notify all observers that are attached to this observable. */ + void notify (T... args) const + { + if (observer_debug) + fprintf_unfiltered (gdb_stdlog, "observable %s notify() called\n", + m_name); + for (auto &&e : m_observers) + e.second (args...); + } + +private: + + std::vector<std::pair<const token *, func_type>> m_observers; + const char *m_name; +}; + +} /* namespace observers */ + +} /* namespace gdb */ + +#endif /* COMMON_OBSERVABLE_H */ diff --git a/gdbsupport/offset-type.h b/gdbsupport/offset-type.h new file mode 100644 index 0000000..b68cb45 --- /dev/null +++ b/gdbsupport/offset-type.h @@ -0,0 +1,133 @@ +/* Offset types for GDB. + + Copyright (C) 2017-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +/* Define an "offset" type. Offset types are distinct integer types + that are used to represent an offset into anything that is + addressable. For example, an offset into a DWARF debug section. + The idea is catch mixing unrelated offset types at compile time, in + code that needs to manipulate multiple different kinds of offsets + that are easily confused. They're safer to use than native + integers, because they have no implicit conversion to anything. + And also, since they're implemented as "enum class" strong + typedefs, they're still integers ABI-wise, making them a bit more + efficient than wrapper structs on some ABIs. + + Some properties of offset types, loosely modeled on pointers: + + - You can compare offsets of the same type for equality and order. + You can't compare an offset with an unrelated type. + + - You can add/substract an integer to/from an offset, which gives + you back a shifted offset. + + - You can subtract two offsets of the same type, which gives you + back the delta as an integer (of the enum class's underlying + type), not as an offset type. + + - You can't add two offsets of the same type, as that would not + make sense. + + However, unlike pointers, you can't deference offset types. */ + +#ifndef COMMON_OFFSET_TYPE_H +#define COMMON_OFFSET_TYPE_H + +/* Declare TYPE as being an offset type. This declares the type and + enables the operators defined below. */ +#define DEFINE_OFFSET_TYPE(TYPE, UNDERLYING) \ + enum class TYPE : UNDERLYING {}; \ + void is_offset_type (TYPE) + +/* The macro macro is all you need to know use offset types. The rest + below is all implementation detail. */ + +/* For each enum class type that you want to support arithmetic + operators, declare an "is_offset_type" overload that has exactly + one parameter, of type that enum class. E.g.,: + + void is_offset_type (sect_offset); + + The function does not need to be defined, only declared. + DEFINE_OFFSET_TYPE declares this. + + A function declaration is preferred over a traits type, because the + former allows calling the DEFINE_OFFSET_TYPE macro inside a + namespace to define the corresponding offset type in that + namespace. The compiler finds the corresponding is_offset_type + function via ADL. +*/ + +/* Adding or subtracting an integer to an offset type shifts the + offset. This is like "PTR = PTR + INT" and "PTR += INT". */ + +#define DEFINE_OFFSET_ARITHM_OP(OP) \ + template<typename E, \ + typename = decltype (is_offset_type (std::declval<E> ()))> \ + constexpr E \ + operator OP (E lhs, typename std::underlying_type<E>::type rhs) \ + { \ + using underlying = typename std::underlying_type<E>::type; \ + return (E) (static_cast<underlying> (lhs) OP rhs); \ + } \ + \ + template<typename E, \ + typename = decltype (is_offset_type (std::declval<E> ()))> \ + constexpr E \ + operator OP (typename std::underlying_type<E>::type lhs, E rhs) \ + { \ + using underlying = typename std::underlying_type<E>::type; \ + return (E) (lhs OP static_cast<underlying> (rhs)); \ + } \ + \ + template<typename E, \ + typename = decltype (is_offset_type (std::declval<E> ()))> \ + E & \ + operator OP ## = (E &lhs, typename std::underlying_type<E>::type rhs) \ + { \ + using underlying = typename std::underlying_type<E>::type; \ + lhs = (E) (static_cast<underlying> (lhs) OP rhs); \ + return lhs; \ + } + +DEFINE_OFFSET_ARITHM_OP(+) +DEFINE_OFFSET_ARITHM_OP(-) + +/* Adding two offset types doesn't make sense, just like "PTR + PTR" + doesn't make sense. This is defined as a deleted function so that + a compile error easily brings you to this comment. */ + +template<typename E, + typename = decltype (is_offset_type (std::declval<E> ()))> +constexpr typename std::underlying_type<E>::type +operator+ (E lhs, E rhs) = delete; + +/* Subtracting two offset types, however, gives you back the + difference between the offsets, as an underlying type. Similar to + how "PTR2 - PTR1" returns a ptrdiff_t. */ + +template<typename E, + typename = decltype (is_offset_type (std::declval<E> ()))> +constexpr typename std::underlying_type<E>::type +operator- (E lhs, E rhs) +{ + using underlying = typename std::underlying_type<E>::type; + return static_cast<underlying> (lhs) - static_cast<underlying> (rhs); +} + +#endif /* COMMON_OFFSET_TYPE_H */ diff --git a/gdbsupport/parallel-for.h b/gdbsupport/parallel-for.h new file mode 100644 index 0000000..2545152 --- /dev/null +++ b/gdbsupport/parallel-for.h @@ -0,0 +1,86 @@ +/* Parallel for loops + + Copyright (C) 2019-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef GDBSUPPORT_PARALLEL_FOR_H +#define GDBSUPPORT_PARALLEL_FOR_H + +#include <algorithm> +#if CXX_STD_THREAD +#include <thread> +#include "gdbsupport/thread-pool.h" +#endif + +namespace gdb +{ + +/* A very simple "parallel for". This splits the range of iterators + into subranges, and then passes each subrange to the callback. The + work may or may not be done in separate threads. + + This approach was chosen over having the callback work on single + items because it makes it simple for the caller to do + once-per-subrange initialization and destruction. */ + +template<class RandomIt, class RangeFunction> +void +parallel_for_each (RandomIt first, RandomIt last, RangeFunction callback) +{ +#if CXX_STD_THREAD + /* So we can use a local array below. */ + const size_t local_max = 16; + size_t n_threads = std::min (thread_pool::g_thread_pool->thread_count (), + local_max); + size_t n_actual_threads = 0; + std::future<void> futures[local_max]; + + size_t n_elements = last - first; + if (n_threads > 1) + { + /* Arbitrarily require that there should be at least 10 elements + in a thread. */ + if (n_elements / n_threads < 10) + n_threads = std::max (n_elements / 10, (size_t) 1); + size_t elts_per_thread = n_elements / n_threads; + n_actual_threads = n_threads - 1; + for (int i = 0; i < n_actual_threads; ++i) + { + RandomIt end = first + elts_per_thread; + auto task = [=] () + { + callback (first, end); + }; + + futures[i] = gdb::thread_pool::g_thread_pool->post_task (task); + first = end; + } + } +#endif /* CXX_STD_THREAD */ + + /* Process all the remaining elements in the main thread. */ + callback (first, last); + +#if CXX_STD_THREAD + for (int i = 0; i < n_actual_threads; ++i) + futures[i].wait (); +#endif /* CXX_STD_THREAD */ +} + +} + +#endif /* GDBSUPPORT_PARALLEL_FOR_H */ diff --git a/gdbsupport/pathstuff.c b/gdbsupport/pathstuff.c new file mode 100644 index 0000000..1f60fd0 --- /dev/null +++ b/gdbsupport/pathstuff.c @@ -0,0 +1,290 @@ +/* Path manipulation routines for GDB and gdbserver. + + Copyright (C) 1986-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "common-defs.h" +#include "pathstuff.h" +#include "host-defs.h" +#include "filenames.h" +#include "gdb_tilde_expand.h" + +#ifdef USE_WIN32API +#include <windows.h> +#endif + +/* See gdbsupport/pathstuff.h. */ + +gdb::unique_xmalloc_ptr<char> +gdb_realpath (const char *filename) +{ +/* On most hosts, we rely on canonicalize_file_name to compute + the FILENAME's realpath. + + But the situation is slightly more complex on Windows, due to some + versions of GCC which were reported to generate paths where + backlashes (the directory separator) were doubled. For instance: + c:\\some\\double\\slashes\\dir + ... instead of ... + c:\some\double\slashes\dir + Those double-slashes were getting in the way when comparing paths, + for instance when trying to insert a breakpoint as follow: + (gdb) b c:/some/double/slashes/dir/foo.c:4 + No source file named c:/some/double/slashes/dir/foo.c:4. + (gdb) b c:\some\double\slashes\dir\foo.c:4 + No source file named c:\some\double\slashes\dir\foo.c:4. + To prevent this from happening, we need this function to always + strip those extra backslashes. While canonicalize_file_name does + perform this simplification, it only works when the path is valid. + Since the simplification would be useful even if the path is not + valid (one can always set a breakpoint on a file, even if the file + does not exist locally), we rely instead on GetFullPathName to + perform the canonicalization. */ + +#if defined (_WIN32) + { + char buf[MAX_PATH]; + DWORD len = GetFullPathName (filename, MAX_PATH, buf, NULL); + + /* The file system is case-insensitive but case-preserving. + So it is important we do not lowercase the path. Otherwise, + we might not be able to display the original casing in a given + path. */ + if (len > 0 && len < MAX_PATH) + return make_unique_xstrdup (buf); + } +#else + { + char *rp = canonicalize_file_name (filename); + + if (rp != NULL) + return gdb::unique_xmalloc_ptr<char> (rp); + } +#endif + + /* This system is a lost cause, just dup the buffer. */ + return make_unique_xstrdup (filename); +} + +/* See gdbsupport/pathstuff.h. */ + +gdb::unique_xmalloc_ptr<char> +gdb_realpath_keepfile (const char *filename) +{ + const char *base_name = lbasename (filename); + char *dir_name; + char *result; + + /* Extract the basename of filename, and return immediately + a copy of filename if it does not contain any directory prefix. */ + if (base_name == filename) + return make_unique_xstrdup (filename); + + dir_name = (char *) alloca ((size_t) (base_name - filename + 2)); + /* Allocate enough space to store the dir_name + plus one extra + character sometimes needed under Windows (see below), and + then the closing \000 character. */ + strncpy (dir_name, filename, base_name - filename); + dir_name[base_name - filename] = '\000'; + +#ifdef HAVE_DOS_BASED_FILE_SYSTEM + /* We need to be careful when filename is of the form 'd:foo', which + is equivalent of d:./foo, which is totally different from d:/foo. */ + if (strlen (dir_name) == 2 && isalpha (dir_name[0]) && dir_name[1] == ':') + { + dir_name[2] = '.'; + dir_name[3] = '\000'; + } +#endif + + /* Canonicalize the directory prefix, and build the resulting + filename. If the dirname realpath already contains an ending + directory separator, avoid doubling it. */ + gdb::unique_xmalloc_ptr<char> path_storage = gdb_realpath (dir_name); + const char *real_path = path_storage.get (); + if (IS_DIR_SEPARATOR (real_path[strlen (real_path) - 1])) + result = concat (real_path, base_name, (char *) NULL); + else + result = concat (real_path, SLASH_STRING, base_name, (char *) NULL); + + return gdb::unique_xmalloc_ptr<char> (result); +} + +/* See gdbsupport/pathstuff.h. */ + +gdb::unique_xmalloc_ptr<char> +gdb_abspath (const char *path) +{ + gdb_assert (path != NULL && path[0] != '\0'); + + if (path[0] == '~') + return gdb_tilde_expand_up (path); + + if (IS_ABSOLUTE_PATH (path) || current_directory == NULL) + return make_unique_xstrdup (path); + + /* Beware the // my son, the Emacs barfs, the botch that catch... */ + return gdb::unique_xmalloc_ptr<char> + (concat (current_directory, + IS_DIR_SEPARATOR (current_directory[strlen (current_directory) - 1]) + ? "" : SLASH_STRING, + path, (char *) NULL)); +} + +/* See gdbsupport/pathstuff.h. */ + +const char * +child_path (const char *parent, const char *child) +{ + /* The child path must start with the parent path. */ + size_t parent_len = strlen (parent); + if (filename_ncmp (parent, child, parent_len) != 0) + return NULL; + + /* The parent path must be a directory and the child must contain at + least one component underneath the parent. */ + const char *child_component; + if (parent_len > 0 && IS_DIR_SEPARATOR (parent[parent_len - 1])) + { + /* The parent path ends in a directory separator, so it is a + directory. The first child component starts after the common + prefix. */ + child_component = child + parent_len; + } + else + { + /* The parent path does not end in a directory separator. The + first character in the child after the common prefix must be + a directory separator. + + Note that CHILD must hold at least parent_len characters for + filename_ncmp to return zero. If the character at parent_len + is nul due to CHILD containing the same path as PARENT, the + IS_DIR_SEPARATOR check will fail here. */ + if (!IS_DIR_SEPARATOR (child[parent_len])) + return NULL; + + /* The first child component starts after the separator after the + common prefix. */ + child_component = child + parent_len + 1; + } + + /* The child must contain at least one non-separator character after + the parent. */ + while (*child_component != '\0') + { + if (!IS_DIR_SEPARATOR (*child_component)) + return child_component; + + child_component++; + } + return NULL; +} + +/* See gdbsupport/pathstuff.h. */ + +bool +contains_dir_separator (const char *path) +{ + for (; *path != '\0'; path++) + { + if (IS_DIR_SEPARATOR (*path)) + return true; + } + + return false; +} + +/* See gdbsupport/pathstuff.h. */ + +std::string +get_standard_cache_dir () +{ +#ifdef __APPLE__ +#define HOME_CACHE_DIR "Library/Caches" +#else +#define HOME_CACHE_DIR ".cache" +#endif + +#ifndef __APPLE__ + const char *xdg_cache_home = getenv ("XDG_CACHE_HOME"); + if (xdg_cache_home != NULL) + { + /* Make sure the path is absolute and tilde-expanded. */ + gdb::unique_xmalloc_ptr<char> abs (gdb_abspath (xdg_cache_home)); + return string_printf ("%s/gdb", abs.get ()); + } +#endif + + const char *home = getenv ("HOME"); + if (home != NULL) + { + /* Make sure the path is absolute and tilde-expanded. */ + gdb::unique_xmalloc_ptr<char> abs (gdb_abspath (home)); + return string_printf ("%s/" HOME_CACHE_DIR "/gdb", abs.get ()); + } + + return {}; +} + +/* See gdbsupport/pathstuff.h. */ + +std::string +get_standard_temp_dir () +{ +#ifdef WIN32 + const char *tmp = getenv ("TMP"); + if (tmp != nullptr) + return tmp; + + tmp = getenv ("TEMP"); + if (tmp != nullptr) + return tmp; + + error (_("Couldn't find temp dir path, both TMP and TEMP are unset.")); + +#else + const char *tmp = getenv ("TMPDIR"); + if (tmp != nullptr) + return tmp; + + return "/tmp"; +#endif +} + +/* See gdbsupport/pathstuff.h. */ + +const char * +get_shell () +{ + const char *ret = getenv ("SHELL"); + if (ret == NULL) + ret = "/bin/sh"; + + return ret; +} + +/* See gdbsupport/pathstuff.h. */ + +gdb::char_vector +make_temp_filename (const std::string &f) +{ + gdb::char_vector filename_temp (f.length () + 8); + strcpy (filename_temp.data (), f.c_str ()); + strcat (filename_temp.data () + f.size (), "-XXXXXX"); + return filename_temp; +} diff --git a/gdbsupport/pathstuff.h b/gdbsupport/pathstuff.h new file mode 100644 index 0000000..4bc0d89 --- /dev/null +++ b/gdbsupport/pathstuff.h @@ -0,0 +1,98 @@ +/* Path manipulation routines for GDB and gdbserver. + + Copyright (C) 1986-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_PATHSTUFF_H +#define COMMON_PATHSTUFF_H + +#include "gdbsupport/byte-vector.h" + +/* Path utilities. */ + +/* Return the real path of FILENAME, expanding all the symbolic links. + + Contrary to "gdb_abspath", this function does not use + CURRENT_DIRECTORY for path expansion. Instead, it relies on the + current working directory (CWD) of GDB or gdbserver. */ + +extern gdb::unique_xmalloc_ptr<char> gdb_realpath (const char *filename); + +/* Return a copy of FILENAME, with its directory prefix canonicalized + by gdb_realpath. */ + +extern gdb::unique_xmalloc_ptr<char> + gdb_realpath_keepfile (const char *filename); + +/* Return PATH in absolute form, performing tilde-expansion if necessary. + PATH cannot be NULL or the empty string. + This does not resolve symlinks however, use gdb_realpath for that. + + Contrary to "gdb_realpath", this function uses CURRENT_DIRECTORY + for the path expansion. This may lead to scenarios the current + working directory (CWD) is different than CURRENT_DIRECTORY. + + If CURRENT_DIRECTORY is NULL, this function returns a copy of + PATH. */ + +extern gdb::unique_xmalloc_ptr<char> gdb_abspath (const char *path); + +/* If the path in CHILD is a child of the path in PARENT, return a + pointer to the first component in the CHILD's pathname below the + PARENT. Otherwise, return NULL. */ + +extern const char *child_path (const char *parent, const char *child); + +/* Return whether PATH contains a directory separator character. */ + +extern bool contains_dir_separator (const char *path); + +/* Get the usual user cache directory for the current platform. + + On Linux, it follows the XDG Base Directory specification: use + $XDG_CACHE_HOME/gdb if the XDG_CACHE_HOME environment variable is + defined, otherwise $HOME/.cache. + + On macOS, it follows the local convention and uses + ~/Library/Caches/gdb. + + The return value is absolute and tilde-expanded. Return an empty + string if neither XDG_CACHE_HOME (on Linux) or HOME are defined. */ + +extern std::string get_standard_cache_dir (); + +/* Get the usual temporary directory for the current platform. + + On Windows, this is the TMP or TEMP environment variable. + + On the rest, this is the TMPDIR environment variable, if defined, else /tmp. + + Throw an exception on error. */ + +extern std::string get_standard_temp_dir (); + +/* Return the file name of the user's shell. Normally this comes from + the SHELL environment variable. */ + +extern const char *get_shell (); + +/* Make a filename suitable to pass to mkstemp based on F (e.g. + /tmp/foo -> /tmp/foo-XXXXXX). */ + +extern gdb::char_vector make_temp_filename (const std::string &f); + +#endif /* COMMON_PATHSTUFF_H */ diff --git a/gdbsupport/poison.h b/gdbsupport/poison.h new file mode 100644 index 0000000..5e1b2cc --- /dev/null +++ b/gdbsupport/poison.h @@ -0,0 +1,248 @@ +/* Poison symbols at compile time. + + Copyright (C) 2017-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_POISON_H +#define COMMON_POISON_H + +#include "traits.h" +#include "obstack.h" + +/* Poison memset of non-POD types. The idea is catching invalid + initialization of non-POD structs that is easy to be introduced as + side effect of refactoring. For example, say this: + + struct S { VEC(foo_s) *m_data; }; + +is converted to this at some point: + + struct S { + S() { m_data.reserve (10); } + std::vector<foo> m_data; + }; + +and old code was initializing S objects like this: + + struct S s; + memset (&s, 0, sizeof (S)); // whoops, now wipes vector. + +Declaring memset as deleted for non-POD types makes the memset above +be a compile-time error. */ + +/* Helper for SFINAE. True if "T *" is memsettable. I.e., if T is + either void, or POD. */ +template<typename T> +struct IsMemsettable + : gdb::Or<std::is_void<T>, + std::is_pod<T>> +{}; + +template <typename T, + typename = gdb::Requires<gdb::Not<IsMemsettable<T>>>> +void *memset (T *s, int c, size_t n) = delete; + +#if HAVE_IS_TRIVIALLY_COPYABLE + +/* Similarly, poison memcpy and memmove of non trivially-copyable + types, which is undefined. */ + +/* True if "T *" is relocatable. I.e., copyable with memcpy/memmove. + I.e., T is either trivially copyable, or void. */ +template<typename T> +struct IsRelocatable + : gdb::Or<std::is_void<T>, + std::is_trivially_copyable<T>> +{}; + +/* True if both source and destination are relocatable. */ + +template <typename D, typename S> +using BothAreRelocatable + = gdb::And<IsRelocatable<D>, IsRelocatable<S>>; + +template <typename D, typename S, + typename = gdb::Requires<gdb::Not<BothAreRelocatable<D, S>>>> +void *memcpy (D *dest, const S *src, size_t n) = delete; + +template <typename D, typename S, + typename = gdb::Requires<gdb::Not<BothAreRelocatable<D, S>>>> +void *memmove (D *dest, const S *src, size_t n) = delete; + +#endif /* HAVE_IS_TRIVIALLY_COPYABLE */ + +/* Poison XNEW and friends to catch usages of malloc-style allocations on + objects that require new/delete. */ + +template<typename T> +#if HAVE_IS_TRIVIALLY_CONSTRUCTIBLE +using IsMallocable = std::is_trivially_constructible<T>; +#else +using IsMallocable = std::true_type; +#endif + +template<typename T> +using IsFreeable = gdb::Or<std::is_trivially_destructible<T>, std::is_void<T>>; + +template <typename T, typename = gdb::Requires<gdb::Not<IsFreeable<T>>>> +void free (T *ptr) = delete; + +template<typename T> +static T * +xnew () +{ + static_assert (IsMallocable<T>::value, "Trying to use XNEW with a non-POD \ +data type. Use operator new instead."); + return XNEW (T); +} + +#undef XNEW +#define XNEW(T) xnew<T>() + +template<typename T> +static T * +xcnew () +{ + static_assert (IsMallocable<T>::value, "Trying to use XCNEW with a non-POD \ +data type. Use operator new instead."); + return XCNEW (T); +} + +#undef XCNEW +#define XCNEW(T) xcnew<T>() + +template<typename T> +static void +xdelete (T *p) +{ + static_assert (IsFreeable<T>::value, "Trying to use XDELETE with a non-POD \ +data type. Use operator delete instead."); + XDELETE (p); +} + +#undef XDELETE +#define XDELETE(P) xdelete (P) + +template<typename T> +static T * +xnewvec (size_t n) +{ + static_assert (IsMallocable<T>::value, "Trying to use XNEWVEC with a \ +non-POD data type. Use operator new[] (or std::vector) instead."); + return XNEWVEC (T, n); +} + +#undef XNEWVEC +#define XNEWVEC(T, N) xnewvec<T> (N) + +template<typename T> +static T * +xcnewvec (size_t n) +{ + static_assert (IsMallocable<T>::value, "Trying to use XCNEWVEC with a \ +non-POD data type. Use operator new[] (or std::vector) instead."); + return XCNEWVEC (T, n); +} + +#undef XCNEWVEC +#define XCNEWVEC(T, N) xcnewvec<T> (N) + +template<typename T> +static T * +xresizevec (T *p, size_t n) +{ + static_assert (IsMallocable<T>::value, "Trying to use XRESIZEVEC with a \ +non-POD data type."); + return XRESIZEVEC (T, p, n); +} + +#undef XRESIZEVEC +#define XRESIZEVEC(T, P, N) xresizevec<T> (P, N) + +template<typename T> +static void +xdeletevec (T *p) +{ + static_assert (IsFreeable<T>::value, "Trying to use XDELETEVEC with a \ +non-POD data type. Use operator delete[] (or std::vector) instead."); + XDELETEVEC (p); +} + +#undef XDELETEVEC +#define XDELETEVEC(P) xdeletevec (P) + +template<typename T> +static T * +xnewvar (size_t s) +{ + static_assert (IsMallocable<T>::value, "Trying to use XNEWVAR with a \ +non-POD data type."); + return XNEWVAR (T, s);; +} + +#undef XNEWVAR +#define XNEWVAR(T, S) xnewvar<T> (S) + +template<typename T> +static T * +xcnewvar (size_t s) +{ + static_assert (IsMallocable<T>::value, "Trying to use XCNEWVAR with a \ +non-POD data type."); + return XCNEWVAR (T, s); +} + +#undef XCNEWVAR +#define XCNEWVAR(T, S) xcnewvar<T> (S) + +template<typename T> +static T * +xresizevar (T *p, size_t s) +{ + static_assert (IsMallocable<T>::value, "Trying to use XRESIZEVAR with a \ +non-POD data type."); + return XRESIZEVAR (T, p, s); +} + +#undef XRESIZEVAR +#define XRESIZEVAR(T, P, S) xresizevar<T> (P, S) + +template<typename T> +static T * +xobnew (obstack *ob) +{ + static_assert (IsMallocable<T>::value, "Trying to use XOBNEW with a \ +non-POD data type."); + return XOBNEW (ob, T); +} + +#undef XOBNEW +#define XOBNEW(O, T) xobnew<T> (O) + +template<typename T> +static T * +xobnewvec (obstack *ob, size_t n) +{ + static_assert (IsMallocable<T>::value, "Trying to use XOBNEWVEC with a \ +non-POD data type."); + return XOBNEWVEC (ob, T, n); +} + +#undef XOBNEWVEC +#define XOBNEWVEC(O, T, N) xobnewvec<T> (O, N) + +#endif /* COMMON_POISON_H */ diff --git a/gdbsupport/preprocessor.h b/gdbsupport/preprocessor.h new file mode 100644 index 0000000..6130280 --- /dev/null +++ b/gdbsupport/preprocessor.h @@ -0,0 +1,35 @@ +/* Copyright (C) 2017-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_PREPROCESSOR_H +#define COMMON_PREPROCESSOR_H + +/* Generally useful preprocessor bits. */ + +/* Concatenate two tokens. */ +#define CONCAT_1(a, b) a ## b +#define CONCAT(a, b) CONCAT_1 (a, b) + +/* Stringification. */ +#define STRINGIFY_1(x) #x +#define STRINGIFY(x) STRINGIFY_1 (x) + +/* Escape parens out. Useful if you need to pass an argument that + includes commas to another macro. */ +#define ESC_PARENS(...) __VA_ARGS__ + +#endif /* COMMON_PREPROCESSOR_H */ diff --git a/gdbsupport/print-utils.c b/gdbsupport/print-utils.c new file mode 100644 index 0000000..a8d8681 --- /dev/null +++ b/gdbsupport/print-utils.c @@ -0,0 +1,326 @@ +/* Cell-based print utility routines for GDB, the GNU debugger. + + Copyright (C) 1986-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "common-defs.h" +#include "print-utils.h" +/* Temporary storage using circular buffer. */ + +/* Number of cells in the circular buffer. */ +#define NUMCELLS 16 + +/* Return the next entry in the circular buffer. */ + +char * +get_print_cell (void) +{ + static char buf[NUMCELLS][PRINT_CELL_SIZE]; + static int cell = 0; + + if (++cell >= NUMCELLS) + cell = 0; + return buf[cell]; +} + +static char * +decimal2str (const char *sign, ULONGEST addr, int width) +{ + /* Steal code from valprint.c:print_decimal(). Should this worry + about the real size of addr as the above does? */ + unsigned long temp[3]; + char *str = get_print_cell (); + int i = 0; + + do + { + temp[i] = addr % (1000 * 1000 * 1000); + addr /= (1000 * 1000 * 1000); + i++; + width -= 9; + } + while (addr != 0 && i < (sizeof (temp) / sizeof (temp[0]))); + + width += 9; + if (width < 0) + width = 0; + + switch (i) + { + case 1: + xsnprintf (str, PRINT_CELL_SIZE, "%s%0*lu", sign, width, temp[0]); + break; + case 2: + xsnprintf (str, PRINT_CELL_SIZE, "%s%0*lu%09lu", sign, width, + temp[1], temp[0]); + break; + case 3: + xsnprintf (str, PRINT_CELL_SIZE, "%s%0*lu%09lu%09lu", sign, width, + temp[2], temp[1], temp[0]); + break; + default: + internal_error (__FILE__, __LINE__, + _("failed internal consistency check")); + } + + return str; +} + +static char * +octal2str (ULONGEST addr, int width) +{ + unsigned long temp[3]; + char *str = get_print_cell (); + int i = 0; + + do + { + temp[i] = addr % (0100000 * 0100000); + addr /= (0100000 * 0100000); + i++; + width -= 10; + } + while (addr != 0 && i < (sizeof (temp) / sizeof (temp[0]))); + + width += 10; + if (width < 0) + width = 0; + + switch (i) + { + case 1: + if (temp[0] == 0) + xsnprintf (str, PRINT_CELL_SIZE, "%*o", width, 0); + else + xsnprintf (str, PRINT_CELL_SIZE, "0%0*lo", width, temp[0]); + break; + case 2: + xsnprintf (str, PRINT_CELL_SIZE, "0%0*lo%010lo", width, temp[1], temp[0]); + break; + case 3: + xsnprintf (str, PRINT_CELL_SIZE, "0%0*lo%010lo%010lo", width, + temp[2], temp[1], temp[0]); + break; + default: + internal_error (__FILE__, __LINE__, + _("failed internal consistency check")); + } + + return str; +} + +/* See print-utils.h. */ + +char * +pulongest (ULONGEST u) +{ + return decimal2str ("", u, 0); +} + +/* See print-utils.h. */ + +char * +plongest (LONGEST l) +{ + if (l < 0) + return decimal2str ("-", -l, 0); + else + return decimal2str ("", l, 0); +} + +/* Eliminate warning from compiler on 32-bit systems. */ +static int thirty_two = 32; + +/* See print-utils.h. */ + +char * +phex (ULONGEST l, int sizeof_l) +{ + char *str; + + switch (sizeof_l) + { + case 8: + str = get_print_cell (); + xsnprintf (str, PRINT_CELL_SIZE, "%08lx%08lx", + (unsigned long) (l >> thirty_two), + (unsigned long) (l & 0xffffffff)); + break; + case 4: + str = get_print_cell (); + xsnprintf (str, PRINT_CELL_SIZE, "%08lx", (unsigned long) l); + break; + case 2: + str = get_print_cell (); + xsnprintf (str, PRINT_CELL_SIZE, "%04x", (unsigned short) (l & 0xffff)); + break; + default: + str = phex (l, sizeof (l)); + break; + } + + return str; +} + +/* See print-utils.h. */ + +char * +phex_nz (ULONGEST l, int sizeof_l) +{ + char *str; + + switch (sizeof_l) + { + case 8: + { + unsigned long high = (unsigned long) (l >> thirty_two); + + str = get_print_cell (); + if (high == 0) + xsnprintf (str, PRINT_CELL_SIZE, "%lx", + (unsigned long) (l & 0xffffffff)); + else + xsnprintf (str, PRINT_CELL_SIZE, "%lx%08lx", high, + (unsigned long) (l & 0xffffffff)); + break; + } + case 4: + str = get_print_cell (); + xsnprintf (str, PRINT_CELL_SIZE, "%lx", (unsigned long) l); + break; + case 2: + str = get_print_cell (); + xsnprintf (str, PRINT_CELL_SIZE, "%x", (unsigned short) (l & 0xffff)); + break; + default: + str = phex_nz (l, sizeof (l)); + break; + } + + return str; +} + +/* See print-utils.h. */ + +char * +hex_string (LONGEST num) +{ + char *result = get_print_cell (); + + xsnprintf (result, PRINT_CELL_SIZE, "0x%s", phex_nz (num, sizeof (num))); + return result; +} + +/* See print-utils.h. */ + +char * +hex_string_custom (LONGEST num, int width) +{ + char *result = get_print_cell (); + char *result_end = result + PRINT_CELL_SIZE - 1; + const char *hex = phex_nz (num, sizeof (num)); + int hex_len = strlen (hex); + + if (hex_len > width) + width = hex_len; + if (width + 2 >= PRINT_CELL_SIZE) + internal_error (__FILE__, __LINE__, _("\ +hex_string_custom: insufficient space to store result")); + + strcpy (result_end - width - 2, "0x"); + memset (result_end - width, '0', width); + strcpy (result_end - hex_len, hex); + return result_end - width - 2; +} + +/* See print-utils.h. */ + +char * +int_string (LONGEST val, int radix, int is_signed, int width, + int use_c_format) +{ + switch (radix) + { + case 16: + { + char *result; + + if (width == 0) + result = hex_string (val); + else + result = hex_string_custom (val, width); + if (! use_c_format) + result += 2; + return result; + } + case 10: + { + if (is_signed && val < 0) + return decimal2str ("-", -val, width); + else + return decimal2str ("", val, width); + } + case 8: + { + char *result = octal2str (val, width); + + if (use_c_format || val == 0) + return result; + else + return result + 1; + } + default: + internal_error (__FILE__, __LINE__, + _("failed internal consistency check")); + } +} + +/* See print-utils.h. */ + +const char * +core_addr_to_string (const CORE_ADDR addr) +{ + char *str = get_print_cell (); + + strcpy (str, "0x"); + strcat (str, phex (addr, sizeof (addr))); + return str; +} + +/* See print-utils.h. */ + +const char * +core_addr_to_string_nz (const CORE_ADDR addr) +{ + char *str = get_print_cell (); + + strcpy (str, "0x"); + strcat (str, phex_nz (addr, sizeof (addr))); + return str; +} + +/* See print-utils.h. */ + +const char * +host_address_to_string_1 (const void *addr) +{ + char *str = get_print_cell (); + + xsnprintf (str, PRINT_CELL_SIZE, "0x%s", + phex_nz ((uintptr_t) addr, sizeof (addr))); + return str; +} diff --git a/gdbsupport/print-utils.h b/gdbsupport/print-utils.h new file mode 100644 index 0000000..7541791 --- /dev/null +++ b/gdbsupport/print-utils.h @@ -0,0 +1,85 @@ +/* Cell-based print utility routines for GDB, the GNU debugger. + + Copyright (C) 1986-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_PRINT_UTILS_H +#define COMMON_PRINT_UTILS_H + +/* How many characters (including the terminating null byte) fit in a + cell. */ +#define PRINT_CELL_SIZE 50 + +/* %u for ULONGEST. The result is stored in a circular static buffer, + NUMCELLS deep. */ + +extern char *pulongest (ULONGEST u); + +/* %d for LONGEST. The result is stored in a circular static buffer, + NUMCELLS deep. */ + +extern char *plongest (LONGEST l); + +/* Convert a ULONGEST into a HEX string, like %lx, with leading zeros. + The result is stored in a circular static buffer, NUMCELLS deep. */ + +extern char *phex (ULONGEST l, int sizeof_l); + +/* Convert a ULONGEST into a HEX string, like %lx, without leading zeros. + The result is stored in a circular static buffer, NUMCELLS deep. */ + +extern char *phex_nz (ULONGEST l, int sizeof_l); + +/* Converts a LONGEST to a C-format hexadecimal literal and stores it + in a static string. Returns a pointer to this string. */ + +extern char *hex_string (LONGEST num); + +/* Converts a LONGEST number to a C-format hexadecimal literal and + stores it in a static string. Returns a pointer to this string + that is valid until the next call. The number is padded on the + left with 0s to at least WIDTH characters. */ + +extern char *hex_string_custom (LONGEST num, int width); + +/* Convert VAL to a numeral in the given radix. For + * radix 10, IS_SIGNED may be true, indicating a signed quantity; + * otherwise VAL is interpreted as unsigned. If WIDTH is supplied, + * it is the minimum width (0-padded if needed). USE_C_FORMAT means + * to use C format in all cases. If it is false, then 'x' + * and 'o' formats do not include a prefix (0x or leading 0). */ + +extern char *int_string (LONGEST val, int radix, int is_signed, int width, + int use_c_format); + +/* Convert a CORE_ADDR into a string. */ + +extern const char *core_addr_to_string (const CORE_ADDR addr); + +extern const char *core_addr_to_string_nz (const CORE_ADDR addr); + +extern const char *host_address_to_string_1 (const void *addr); + +/* Wrapper that avoids adding a pointless cast to all callers. */ +#define host_address_to_string(ADDR) \ + host_address_to_string_1 ((const void *) (ADDR)) + +/* Return the next entry in the circular print buffer. */ + +extern char *get_print_cell (void); + +#endif /* COMMON_PRINT_UTILS_H */ diff --git a/gdbsupport/ptid.c b/gdbsupport/ptid.c new file mode 100644 index 0000000..9638943 --- /dev/null +++ b/gdbsupport/ptid.c @@ -0,0 +1,26 @@ +/* The ptid_t type and common functions operating on it. + + Copyright (C) 1986-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "common-defs.h" +#include "ptid.h" + +/* See ptid.h for these. */ + +ptid_t const null_ptid = ptid_t::make_null (); +ptid_t const minus_one_ptid = ptid_t::make_minus_one (); diff --git a/gdbsupport/ptid.h b/gdbsupport/ptid.h new file mode 100644 index 0000000..ef52d55 --- /dev/null +++ b/gdbsupport/ptid.h @@ -0,0 +1,155 @@ +/* The ptid_t type and common functions operating on it. + + Copyright (C) 1986-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_PTID_H +#define COMMON_PTID_H + +/* The ptid struct is a collection of the various "ids" necessary for + identifying the inferior process/thread being debugged. This + consists of the process id (pid), lightweight process id (lwp) and + thread id (tid). When manipulating ptids, the constructors, + accessors, and predicates declared in this file should be used. Do + NOT access the struct ptid members directly. + + process_stratum targets that handle threading themselves should + prefer using the ptid.lwp field, leaving the ptid.tid field for any + thread_stratum target that might want to sit on top. +*/ + +class ptid_t +{ +public: + /* Must have a trivial defaulted default constructor so that the + type remains POD. */ + ptid_t () noexcept = default; + + /* Make a ptid given the necessary PID, LWP, and TID components. + + A ptid with only a PID (LWP and TID equal to zero) is usually used to + represent a whole process, including all its lwps/threads. */ + + explicit constexpr ptid_t (int pid, long lwp = 0, long tid = 0) + : m_pid (pid), m_lwp (lwp), m_tid (tid) + {} + + /* Fetch the pid (process id) component from the ptid. */ + + constexpr int pid () const + { return m_pid; } + + /* Return true if the ptid's lwp member is non-zero. */ + + constexpr bool lwp_p () const + { return m_lwp != 0; } + + /* Fetch the lwp (lightweight process) component from the ptid. */ + + constexpr long lwp () const + { return m_lwp; } + + /* Return true if the ptid's tid member is non-zero. */ + + constexpr bool tid_p () const + { return m_tid != 0; } + + /* Fetch the tid (thread id) component from a ptid. */ + + constexpr long tid () const + { return m_tid; } + + /* Return true if the ptid represents a whole process, including all its + lwps/threads. Such ptids have the form of (pid, 0, 0), with + pid != -1. */ + + constexpr bool is_pid () const + { + return (*this != make_null () + && *this != make_minus_one () + && m_lwp == 0 + && m_tid == 0); + } + + /* Compare two ptids to see if they are equal. */ + + constexpr bool operator== (const ptid_t &other) const + { + return (m_pid == other.m_pid + && m_lwp == other.m_lwp + && m_tid == other.m_tid); + } + + /* Compare two ptids to see if they are different. */ + + constexpr bool operator!= (const ptid_t &other) const + { + return !(*this == other); + } + + /* Return true if the ptid matches FILTER. FILTER can be the wild + card MINUS_ONE_PTID (all ptids match it); can be a ptid representing + a process (ptid.is_pid () returns true), in which case, all lwps and + threads of that given process match, lwps and threads of other + processes do not; or, it can represent a specific thread, in which + case, only that thread will match true. The ptid must represent a + specific LWP or THREAD, it can never be a wild card. */ + + constexpr bool matches (const ptid_t &filter) const + { + return (/* If filter represents any ptid, it's always a match. */ + filter == make_minus_one () + /* If filter is only a pid, any ptid with that pid + matches. */ + || (filter.is_pid () && m_pid == filter.pid ()) + + /* Otherwise, this ptid only matches if it's exactly equal + to filter. */ + || *this == filter); + } + + /* Make a null ptid. */ + + static constexpr ptid_t make_null () + { return ptid_t (0, 0, 0); } + + /* Make a minus one ptid. */ + + static constexpr ptid_t make_minus_one () + { return ptid_t (-1, 0, 0); } + +private: + /* Process id. */ + int m_pid; + + /* Lightweight process id. */ + long m_lwp; + + /* Thread id. */ + long m_tid; +}; + +/* The null or zero ptid, often used to indicate no process. */ + +extern const ptid_t null_ptid; + +/* The (-1,0,0) ptid, often used to indicate either an error condition + or a "don't care" condition, i.e, "run all threads." */ + +extern const ptid_t minus_one_ptid; + +#endif /* COMMON_PTID_H */ diff --git a/gdbsupport/refcounted-object.h b/gdbsupport/refcounted-object.h new file mode 100644 index 0000000..95a3127 --- /dev/null +++ b/gdbsupport/refcounted-object.h @@ -0,0 +1,70 @@ +/* Base class of intrusively reference-counted objects. + Copyright (C) 2017-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_REFCOUNTED_OBJECT_H +#define COMMON_REFCOUNTED_OBJECT_H + +/* Base class of intrusively reference-countable objects. + Incrementing and decrementing the reference count is an external + responsibility. */ + +class refcounted_object +{ +public: + refcounted_object () = default; + + /* Increase the refcount. */ + void incref () + { + gdb_assert (m_refcount >= 0); + m_refcount++; + } + + /* Decrease the refcount. */ + void decref () + { + m_refcount--; + gdb_assert (m_refcount >= 0); + } + + int refcount () const { return m_refcount; } + +private: + DISABLE_COPY_AND_ASSIGN (refcounted_object); + + /* The reference count. */ + int m_refcount = 0; +}; + +/* A policy class to interface gdb::ref_ptr with a + refcounted_object. */ + +struct refcounted_object_ref_policy +{ + static void incref (refcounted_object *ptr) + { + ptr->incref (); + } + + static void decref (refcounted_object *ptr) + { + ptr->decref (); + } +}; + +#endif /* COMMON_REFCOUNTED_OBJECT_H */ diff --git a/gdbsupport/rsp-low.c b/gdbsupport/rsp-low.c new file mode 100644 index 0000000..9bb1660 --- /dev/null +++ b/gdbsupport/rsp-low.c @@ -0,0 +1,307 @@ +/* Low-level RSP routines for GDB, the GNU debugger. + + Copyright (C) 1988-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "common-defs.h" +#include "rsp-low.h" + +/* See rsp-low.h. */ + +int +fromhex (int a) +{ + if (a >= '0' && a <= '9') + return a - '0'; + else if (a >= 'a' && a <= 'f') + return a - 'a' + 10; + else if (a >= 'A' && a <= 'F') + return a - 'A' + 10; + else + error (_("Reply contains invalid hex digit %d"), a); +} + +/* See rsp-low.h. */ + +int +tohex (int nib) +{ + if (nib < 10) + return '0' + nib; + else + return 'a' + nib - 10; +} + +/* Encode 64 bits in 16 chars of hex. */ + +static const char hexchars[] = "0123456789abcdef"; + +static int +ishex (int ch, int *val) +{ + if ((ch >= 'a') && (ch <= 'f')) + { + *val = ch - 'a' + 10; + return 1; + } + if ((ch >= 'A') && (ch <= 'F')) + { + *val = ch - 'A' + 10; + return 1; + } + if ((ch >= '0') && (ch <= '9')) + { + *val = ch - '0'; + return 1; + } + return 0; +} + +/* See rsp-low.h. */ + +char * +pack_nibble (char *buf, int nibble) +{ + *buf++ = hexchars[(nibble & 0x0f)]; + return buf; +} + +/* See rsp-low.h. */ + +char * +pack_hex_byte (char *pkt, int byte) +{ + *pkt++ = hexchars[(byte >> 4) & 0xf]; + *pkt++ = hexchars[(byte & 0xf)]; + return pkt; +} + +/* See rsp-low.h. */ + +const char * +unpack_varlen_hex (const char *buff, /* packet to parse */ + ULONGEST *result) +{ + int nibble; + ULONGEST retval = 0; + + while (ishex (*buff, &nibble)) + { + buff++; + retval = retval << 4; + retval |= nibble & 0x0f; + } + *result = retval; + return buff; +} + +/* See rsp-low.h. */ + +int +hex2bin (const char *hex, gdb_byte *bin, int count) +{ + int i; + + for (i = 0; i < count; i++) + { + if (hex[0] == 0 || hex[1] == 0) + { + /* Hex string is short, or of uneven length. + Return the count that has been converted so far. */ + return i; + } + *bin++ = fromhex (hex[0]) * 16 + fromhex (hex[1]); + hex += 2; + } + return i; +} + +/* See rsp-low.h. */ + +gdb::byte_vector +hex2bin (const char *hex) +{ + size_t bin_len = strlen (hex) / 2; + gdb::byte_vector bin (bin_len); + + hex2bin (hex, bin.data (), bin_len); + + return bin; +} + +/* See rsp-low.h. */ + +std::string +hex2str (const char *hex) +{ + return hex2str (hex, strlen (hex)); +} + +/* See rsp-low.h. */ + +std::string +hex2str (const char *hex, int count) +{ + std::string ret; + + ret.reserve (count); + for (size_t i = 0; i < count; ++i) + { + if (hex[0] == '\0' || hex[1] == '\0') + { + /* Hex string is short, or of uneven length. Return what we + have so far. */ + return ret; + } + ret += fromhex (hex[0]) * 16 + fromhex (hex[1]); + hex += 2; + } + + return ret; +} + +/* See rsp-low.h. */ + +int +bin2hex (const gdb_byte *bin, char *hex, int count) +{ + int i; + + for (i = 0; i < count; i++) + { + *hex++ = tohex ((*bin >> 4) & 0xf); + *hex++ = tohex (*bin++ & 0xf); + } + *hex = 0; + return i; +} + +/* See rsp-low.h. */ + +std::string +bin2hex (const gdb_byte *bin, int count) +{ + std::string ret; + + ret.reserve (count * 2); + for (int i = 0; i < count; ++i) + { + ret += tohex ((*bin >> 4) & 0xf); + ret += tohex (*bin++ & 0xf); + } + + return ret; +} + +/* Return whether byte B needs escaping when sent as part of binary data. */ + +static int +needs_escaping (gdb_byte b) +{ + return b == '$' || b == '#' || b == '}' || b == '*'; +} + +/* See rsp-low.h. */ + +int +remote_escape_output (const gdb_byte *buffer, int len_units, int unit_size, + gdb_byte *out_buf, int *out_len_units, + int out_maxlen_bytes) +{ + int input_unit_index, output_byte_index = 0, byte_index_in_unit; + int number_escape_bytes_needed; + + /* Try to copy integral addressable memory units until + (1) we run out of space or + (2) we copied all of them. */ + for (input_unit_index = 0; + input_unit_index < len_units; + input_unit_index++) + { + /* Find out how many escape bytes we need for this unit. */ + number_escape_bytes_needed = 0; + for (byte_index_in_unit = 0; + byte_index_in_unit < unit_size; + byte_index_in_unit++) + { + int idx = input_unit_index * unit_size + byte_index_in_unit; + gdb_byte b = buffer[idx]; + if (needs_escaping (b)) + number_escape_bytes_needed++; + } + + /* Check if we have room to fit this escaped unit. */ + if (output_byte_index + unit_size + number_escape_bytes_needed > + out_maxlen_bytes) + break; + + /* Copy the unit byte per byte, adding escapes. */ + for (byte_index_in_unit = 0; + byte_index_in_unit < unit_size; + byte_index_in_unit++) + { + int idx = input_unit_index * unit_size + byte_index_in_unit; + gdb_byte b = buffer[idx]; + if (needs_escaping (b)) + { + out_buf[output_byte_index++] = '}'; + out_buf[output_byte_index++] = b ^ 0x20; + } + else + out_buf[output_byte_index++] = b; + } + } + + *out_len_units = input_unit_index; + return output_byte_index; +} + +/* See rsp-low.h. */ + +int +remote_unescape_input (const gdb_byte *buffer, int len, + gdb_byte *out_buf, int out_maxlen) +{ + int input_index, output_index; + int escaped; + + output_index = 0; + escaped = 0; + for (input_index = 0; input_index < len; input_index++) + { + gdb_byte b = buffer[input_index]; + + if (output_index + 1 > out_maxlen) + error (_("Received too much data from the target.")); + + if (escaped) + { + out_buf[output_index++] = b ^ 0x20; + escaped = 0; + } + else if (b == '}') + escaped = 1; + else + out_buf[output_index++] = b; + } + + if (escaped) + error (_("Unmatched escape character in target response.")); + + return output_index; +} + diff --git a/gdbsupport/rsp-low.h b/gdbsupport/rsp-low.h new file mode 100644 index 0000000..84eb839 --- /dev/null +++ b/gdbsupport/rsp-low.h @@ -0,0 +1,101 @@ +/* Low-level RSP routines for GDB, the GNU debugger. + + Copyright (C) 1988-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_RSP_LOW_H +#define COMMON_RSP_LOW_H + +#include "gdbsupport/byte-vector.h" + +/* Convert hex digit A to a number, or throw an exception. */ + +extern int fromhex (int a); + +/* Convert number NIB to a hex digit. */ + +extern int tohex (int nib); + +/* Write a character representing the low order four bits of NIBBLE in + hex to *BUF. Returns BUF+1. */ + +extern char *pack_nibble (char *buf, int nibble); + +/* Write the low byte of BYTE in hex to *BUF. Returns BUF+2. */ + +extern char *pack_hex_byte (char *pkt, int byte); + +/* Read hex digits from BUFF and convert to a number, which is stored + in RESULT. Reads until a non-hex digit is seen. Returns a pointer + to the terminating character. */ + +extern const char *unpack_varlen_hex (const char *buff, ULONGEST *result); + +/* HEX is a string of characters representing hexadecimal digits. + Convert pairs of hex digits to bytes and store sequentially into + BIN. COUNT is the maximum number of characters to convert. This + will convert fewer characters if the number of hex characters + actually seen is odd, or if HEX terminates before COUNT characters. + Returns the number of characters actually converted. */ + +extern int hex2bin (const char *hex, gdb_byte *bin, int count); + +/* Like the above, but return a gdb::byte_vector. */ + +gdb::byte_vector hex2bin (const char *hex); + +/* Like hex2bin, but return a std::string. */ + +extern std::string hex2str (const char *hex); + +/* Like hex2bin, but return a std::string. */ + +extern std::string hex2str (const char *hex, int count); + +/* Convert some bytes to a hexadecimal representation. BIN holds the + bytes to convert. COUNT says how many bytes to convert. The + resulting characters are stored in HEX, followed by a NUL + character. Returns the number of bytes actually converted. */ + +extern int bin2hex (const gdb_byte *bin, char *hex, int count); + +/* Overloaded version of bin2hex that returns a std::string. */ + +extern std::string bin2hex (const gdb_byte *bin, int count); + +/* Convert BUFFER, binary data at least LEN_UNITS addressable memory units + long, into escaped binary data in OUT_BUF. Only copy memory units that fit + completely in OUT_BUF. Set *OUT_LEN_UNITS to the number of units from + BUFFER successfully encoded in OUT_BUF, and return the number of bytes used + in OUT_BUF. The total number of bytes in the output buffer will be at most + OUT_MAXLEN_BYTES. This function properly escapes '*', and so is suitable + for the server side as well as the client. */ + +extern int remote_escape_output (const gdb_byte *buffer, int len_units, + int unit_size, gdb_byte *out_buf, + int *out_len_units, int out_maxlen_bytes); + +/* Convert BUFFER, escaped data LEN bytes long, into binary data + in OUT_BUF. Return the number of bytes written to OUT_BUF. + Raise an error if the total number of bytes exceeds OUT_MAXLEN. + + This function reverses remote_escape_output. */ + +extern int remote_unescape_input (const gdb_byte *buffer, int len, + gdb_byte *out_buf, int out_maxlen); + +#endif /* COMMON_RSP_LOW_H */ diff --git a/gdbsupport/run-time-clock.c b/gdbsupport/run-time-clock.c new file mode 100644 index 0000000..24dc19c --- /dev/null +++ b/gdbsupport/run-time-clock.c @@ -0,0 +1,58 @@ +/* User/system CPU time clocks that follow the std::chrono interface. + Copyright (C) 2016-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "common-defs.h" +#include "run-time-clock.h" +#if defined HAVE_SYS_RESOURCE_H +#include <sys/resource.h> +#endif + +using namespace std::chrono; + +run_time_clock::time_point +run_time_clock::now () noexcept +{ + return time_point (microseconds (get_run_time ())); +} + +#ifdef HAVE_GETRUSAGE +static std::chrono::microseconds +timeval_to_microseconds (struct timeval *tv) +{ + return (seconds (tv->tv_sec) + microseconds (tv->tv_usec)); +} +#endif + +void +run_time_clock::now (user_cpu_time_clock::time_point &user, + system_cpu_time_clock::time_point &system) noexcept +{ +#ifdef HAVE_GETRUSAGE + struct rusage rusage; + + getrusage (RUSAGE_SELF, &rusage); + + microseconds utime = timeval_to_microseconds (&rusage.ru_utime); + microseconds stime = timeval_to_microseconds (&rusage.ru_stime); + user = user_cpu_time_clock::time_point (utime); + system = system_cpu_time_clock::time_point (stime); +#else + user = user_cpu_time_clock::time_point (microseconds (get_run_time ())); + system = system_cpu_time_clock::time_point (microseconds::zero ()); +#endif +} diff --git a/gdbsupport/run-time-clock.h b/gdbsupport/run-time-clock.h new file mode 100644 index 0000000..fef0c34 --- /dev/null +++ b/gdbsupport/run-time-clock.h @@ -0,0 +1,75 @@ +/* User/system CPU time clocks that follow the std::chrono interface. + Copyright (C) 2016-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_RUN_TIME_CLOCK_H +#define COMMON_RUN_TIME_CLOCK_H + +#include <chrono> + +/* Count the total amount of time spent executing in user mode. */ + +struct user_cpu_time_clock +{ + using duration = std::chrono::microseconds; + using rep = duration::rep; + using period = duration::period; + using time_point = std::chrono::time_point<user_cpu_time_clock>; + + static constexpr bool is_steady = true; + + /* Use run_time_clock::now instead. */ + static time_point now () noexcept = delete; +}; + +/* Count the total amount of time spent executing in kernel mode. */ + +struct system_cpu_time_clock +{ + using duration = std::chrono::microseconds; + using rep = duration::rep; + using period = duration::period; + using time_point = std::chrono::time_point<system_cpu_time_clock>; + + static constexpr bool is_steady = true; + + /* Use run_time_clock::now instead. */ + static time_point now () noexcept = delete; +}; + +/* Count the total amount of time spent executing in userspace+kernel + mode. */ + +struct run_time_clock +{ + using duration = std::chrono::microseconds; + using rep = duration::rep; + using period = duration::period; + using time_point = std::chrono::time_point<run_time_clock>; + + static constexpr bool is_steady = true; + + static time_point now () noexcept; + + /* Return the user/system time as separate time points, if + supported. If not supported, then the combined user+kernel time + is returned in USER and SYSTEM is set to zero. */ + static void now (user_cpu_time_clock::time_point &user, + system_cpu_time_clock::time_point &system) noexcept; +}; + +#endif /* COMMON_RUN_TIME_CLOCK_H */ diff --git a/gdbsupport/safe-iterator.h b/gdbsupport/safe-iterator.h new file mode 100644 index 0000000..04fe52a --- /dev/null +++ b/gdbsupport/safe-iterator.h @@ -0,0 +1,135 @@ +/* A safe iterator for GDB, the GNU debugger. + Copyright (C) 2018-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_SAFE_ITERATOR_H +#define COMMON_SAFE_ITERATOR_H + +/* A forward iterator that wraps Iterator, such that when iterating + with iterator IT, it is possible to delete *IT without invalidating + IT. Suitably wrapped in a range type and used with range-for, this + allow convenient patterns like this: + + // range_safe() returns a range type whose begin()/end() methods + // return safe iterators. + for (foo *f : range_safe ()) + { + if (f->should_delete ()) + { + // The ++it operation implicitly done by the range-for is + // still OK after this. + delete f; + } + } +*/ + +template<typename Iterator> +class basic_safe_iterator +{ +public: + typedef basic_safe_iterator self_type; + typedef typename Iterator::value_type value_type; + typedef typename Iterator::reference reference; + typedef typename Iterator::pointer pointer; + typedef typename Iterator::iterator_category iterator_category; + typedef typename Iterator::difference_type difference_type; + + /* Construct using the given argument; the end iterator is default + constructed. */ + template<typename Arg> + explicit basic_safe_iterator (Arg &&arg) + : m_it (std::forward<Arg> (arg)), + m_next (m_it) + { + if (m_it != m_end) + ++m_next; + } + + /* Construct the iterator using the first argument, and construct + the end iterator using the second argument. */ + template<typename Arg> + explicit basic_safe_iterator (Arg &&arg, Arg &&arg2) + : m_it (std::forward<Arg> (arg)), + m_next (m_it), + m_end (std::forward<Arg> (arg2)) + { + if (m_it != m_end) + ++m_next; + } + + /* Create a one-past-end iterator. */ + basic_safe_iterator () + {} + + value_type operator* () const { return *m_it; } + + self_type &operator++ () + { + m_it = m_next; + if (m_it != m_end) + ++m_next; + return *this; + } + + bool operator== (const self_type &other) const + { return m_it == other.m_it; } + + bool operator!= (const self_type &other) const + { return m_it != other.m_it; } + +private: + /* The current element. */ + Iterator m_it {}; + + /* The next element. Always one element ahead of M_IT. */ + Iterator m_next {}; + + /* A one-past-end iterator. */ + Iterator m_end {}; +}; + +/* A range adapter that wraps another range, and then returns safe + iterators wrapping the original range's iterators. */ + +template<typename Range> +class basic_safe_range +{ +public: + + typedef basic_safe_iterator<typename Range::iterator> iterator; + + explicit basic_safe_range (Range range) + : m_range (range) + { + } + + iterator begin () + { + return iterator (m_range.begin (), m_range.end ()); + } + + iterator end () + { + return iterator (m_range.end (), m_range.end ()); + } + +private: + + Range m_range; +}; + +#endif /* COMMON_SAFE_ITERATOR_H */ diff --git a/gdbsupport/safe-strerror.c b/gdbsupport/safe-strerror.c new file mode 100644 index 0000000..5804621 --- /dev/null +++ b/gdbsupport/safe-strerror.c @@ -0,0 +1,56 @@ +/* Safe version of strerror for GDB, the GNU debugger. + + Copyright (C) 2006-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "common-defs.h" +#include <string.h> + +/* There are two different versions of strerror_r; one is GNU-specific, the + other XSI-compliant. They differ in the return type. This overload lets + us choose the right behavior for each return type. We cannot rely on Gnulib + to solve this for us because IPA does not use Gnulib but uses this + function. */ + +/* Called if we have a XSI-compliant strerror_r. */ +ATTRIBUTE_UNUSED static char * +select_strerror_r (int res, char *buf) +{ + return res == 0 ? buf : nullptr; +} + +/* Called if we have a GNU strerror_r. */ +ATTRIBUTE_UNUSED static char * +select_strerror_r (char *res, char *) +{ + return res; +} + +/* Implementation of safe_strerror as defined in common-utils.h. */ + +const char * +safe_strerror (int errnum) +{ + static thread_local char buf[1024]; + + char *res = select_strerror_r (strerror_r (errnum, buf, sizeof (buf)), buf); + if (res != nullptr) + return res; + + xsnprintf (buf, sizeof buf, "(undocumented errno %d)", errnum); + return buf; +} diff --git a/gdbsupport/scope-exit.h b/gdbsupport/scope-exit.h new file mode 100644 index 0000000..192f666 --- /dev/null +++ b/gdbsupport/scope-exit.h @@ -0,0 +1,186 @@ +/* Copyright (C) 2019-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_SCOPE_EXIT_H +#define COMMON_SCOPE_EXIT_H + +#include <functional> +#include <type_traits> +#include "gdbsupport/preprocessor.h" + +/* scope_exit is a general-purpose scope guard that calls its exit + function at the end of the current scope. A scope_exit may be + canceled by calling the "release" method. The API is modeled on + P0052R5 - Generic Scope Guard and RAII Wrapper for the Standard + Library, which is itself based on Andrej Alexandrescu's + ScopeGuard/SCOPE_EXIT. + + There are two forms available: + + - The "make_scope_exit" form allows canceling the scope guard. Use + it like this: + + auto cleanup = make_scope_exit ( <function, function object, lambda> ); + ... + cleanup.release (); // cancel + + - If you don't need to cancel the guard, you can use the SCOPE_EXIT + macro, like this: + + SCOPE_EXIT + { + // any code you like here. + } + + See also forward_scope_exit. +*/ + +/* CRTP base class for cancelable scope_exit-like classes. Implements + the common call-custom-function-from-dtor functionality. Classes + that inherit this implement the on_exit() method, which is called + from scope_exit_base's dtor. */ + +template <typename CRTP> +class scope_exit_base +{ +public: + scope_exit_base () = default; + + ~scope_exit_base () + { + if (!m_released) + { + auto *self = static_cast<CRTP *> (this); + self->on_exit (); + } + } + + /* This is needed for make_scope_exit because copy elision isn't + guaranteed until C++17. An optimizing compiler will usually skip + calling this, but it must exist. */ + scope_exit_base (const scope_exit_base &other) + : m_released (other.m_released) + { + other.m_released = true; + } + + void operator= (const scope_exit_base &) = delete; + + /* If this is called, then the wrapped function will not be called + on destruction. */ + void release () noexcept + { + m_released = true; + } + +private: + + /* True if released. Mutable because of the copy ctor hack + above. */ + mutable bool m_released = false; +}; + +/* The scope_exit class. */ + +template<typename EF> +class scope_exit : public scope_exit_base<scope_exit<EF>> +{ + /* For access to on_exit(). */ + friend scope_exit_base<scope_exit<EF>>; + +public: + + template<typename EFP, + typename = gdb::Requires<std::is_constructible<EF, EFP>>> + scope_exit (EFP &&f) + try : m_exit_function ((!std::is_lvalue_reference<EFP>::value + && std::is_nothrow_constructible<EF, EFP>::value) + ? std::move (f) + : f) + { + } + catch (...) + { + /* "If the initialization of exit_function throws an exception, + calls f()." */ + f (); + } + + template<typename EFP, + typename = gdb::Requires<std::is_constructible<EF, EFP>>> + scope_exit (scope_exit &&rhs) + noexcept (std::is_nothrow_move_constructible<EF>::value + || std::is_nothrow_copy_constructible<EF>::value) + : m_exit_function (std::is_nothrow_constructible<EFP>::value + ? std::move (rhs) + : rhs) + { + rhs.release (); + } + + /* This is needed for make_scope_exit because copy elision isn't + guaranteed until C++17. An optimizing compiler will usually skip + calling this, but it must exist. */ + scope_exit (const scope_exit &other) + : scope_exit_base<scope_exit<EF>> (other), + m_exit_function (other.m_exit_function) + { + } + + void operator= (const scope_exit &) = delete; + void operator= (scope_exit &&) = delete; + +private: + void on_exit () + { + m_exit_function (); + } + + /* The function to call on scope exit. */ + EF m_exit_function; +}; + +template <typename EF> +scope_exit<typename std::decay<EF>::type> +make_scope_exit (EF &&f) +{ + return scope_exit<typename std::decay<EF>::type> (std::forward<EF> (f)); +} + +namespace detail +{ + +enum class scope_exit_lhs {}; + +template<typename EF> +scope_exit<typename std::decay<EF>::type> +operator+ (scope_exit_lhs, EF &&rhs) +{ + return scope_exit<typename std::decay<EF>::type> (std::forward<EF> (rhs)); +} + +} + +/* Register a block of code to run on scope exit. Note that the local + context is captured by reference, which means you should be careful + to avoid inadvertently changing a captured local's value before the + scope exit runs. */ + +#define SCOPE_EXIT \ + auto CONCAT(scope_exit_, __LINE__) = ::detail::scope_exit_lhs () + [&] () + +#endif /* COMMON_SCOPE_EXIT_H */ diff --git a/gdbsupport/scoped_fd.h b/gdbsupport/scoped_fd.h new file mode 100644 index 0000000..f40ce8b --- /dev/null +++ b/gdbsupport/scoped_fd.h @@ -0,0 +1,87 @@ +/* scoped_fd, automatically close a file descriptor + + Copyright (C) 2018-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_SCOPED_FD_H +#define COMMON_SCOPED_FD_H + +#include <unistd.h> +#include "filestuff.h" + +/* A smart-pointer-like class to automatically close a file descriptor. */ + +class scoped_fd +{ +public: + explicit scoped_fd (int fd = -1) noexcept : m_fd (fd) {} + + scoped_fd (scoped_fd &&other) + : m_fd (other.m_fd) + { + other.m_fd = -1; + } + + ~scoped_fd () + { + if (m_fd >= 0) + close (m_fd); + } + + scoped_fd &operator= (scoped_fd &&other) + { + if (m_fd != other.m_fd) + { + if (m_fd >= 0) + close (m_fd); + m_fd = other.m_fd; + other.m_fd = -1; + } + return *this; + } + + DISABLE_COPY_AND_ASSIGN (scoped_fd); + + ATTRIBUTE_UNUSED_RESULT int release () noexcept + { + int fd = m_fd; + m_fd = -1; + return fd; + } + + /* Like release, but return a gdb_file_up that owns the file + descriptor. On success, this scoped_fd will be released. On + failure, return NULL and leave this scoped_fd in possession of + the fd. */ + gdb_file_up to_file (const char *mode) noexcept + { + gdb_file_up result (fdopen (m_fd, mode)); + if (result != nullptr) + m_fd = -1; + return result; + } + + int get () const noexcept + { + return m_fd; + } + +private: + int m_fd; +}; + +#endif /* COMMON_SCOPED_FD_H */ diff --git a/gdbsupport/scoped_mmap.c b/gdbsupport/scoped_mmap.c new file mode 100644 index 0000000..6b424dc --- /dev/null +++ b/gdbsupport/scoped_mmap.c @@ -0,0 +1,49 @@ +/* scoped_mmap, automatically unmap files + + Copyright (C) 2018-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "common-defs.h" +#include "scoped_mmap.h" +#include "scoped_fd.h" +#include "gdbsupport/filestuff.h" + +#ifdef HAVE_SYS_MMAN_H + +scoped_mmap +mmap_file (const char *filename) +{ + scoped_fd fd (gdb_open_cloexec (filename, O_RDONLY, 0)); + if (fd.get () < 0) + perror_with_name (("open")); + + off_t size = lseek (fd.get (), 0, SEEK_END); + if (size < 0) + perror_with_name (("lseek")); + + /* We can't map an empty file. */ + if (size == 0) + error (_("file to mmap is empty")); + + scoped_mmap mmapped_file (nullptr, size, PROT_READ, MAP_PRIVATE, fd.get (), 0); + if (mmapped_file.get () == MAP_FAILED) + perror_with_name (("mmap")); + + return mmapped_file; +} + +#endif /* HAVE_SYS_MMAN_H */ diff --git a/gdbsupport/scoped_mmap.h b/gdbsupport/scoped_mmap.h new file mode 100644 index 0000000..bab988f --- /dev/null +++ b/gdbsupport/scoped_mmap.h @@ -0,0 +1,94 @@ +/* scoped_mmap, automatically unmap files + + Copyright (C) 2018-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_SCOPED_MMAP_H +#define COMMON_SCOPED_MMAP_H + +#ifdef HAVE_SYS_MMAN_H + +#include <sys/mman.h> + +/* A smart-pointer-like class to mmap() and automatically munmap() a memory + mapping. */ + +class scoped_mmap +{ +public: + scoped_mmap () noexcept : m_mem (MAP_FAILED), m_length (0) {} + scoped_mmap (void *addr, size_t length, int prot, int flags, int fd, + off_t offset) noexcept : m_length (length) + { + m_mem = mmap (addr, m_length, prot, flags, fd, offset); + } + + ~scoped_mmap () + { + destroy (); + } + + scoped_mmap (scoped_mmap &&rhs) + { + destroy (); + + m_mem = rhs.m_mem; + m_length = rhs.m_length; + + rhs.m_mem = MAP_FAILED; + rhs.m_length = 0; + } + + DISABLE_COPY_AND_ASSIGN (scoped_mmap); + + ATTRIBUTE_UNUSED_RESULT void *release () noexcept + { + void *mem = m_mem; + m_mem = MAP_FAILED; + m_length = 0; + return mem; + } + + void reset (void *addr, size_t length, int prot, int flags, int fd, + off_t offset) noexcept + { + destroy (); + + m_length = length; + m_mem = mmap (addr, m_length, prot, flags, fd, offset); + } + + size_t size () const noexcept { return m_length; } + void *get () const noexcept { return m_mem; } + +private: + void destroy () + { + if (m_mem != MAP_FAILED) + munmap (m_mem, m_length); + } + + void *m_mem; + size_t m_length; +}; + +/* Map FILENAME in memory. Throw an error if anything goes wrong. */ +scoped_mmap mmap_file (const char *filename); + +#endif /* HAVE_SYS_MMAN_H */ + +#endif /* COMMON_SCOPED_MMAP_H */ diff --git a/gdbsupport/scoped_restore.h b/gdbsupport/scoped_restore.h new file mode 100644 index 0000000..0dca6d0 --- /dev/null +++ b/gdbsupport/scoped_restore.h @@ -0,0 +1,118 @@ +/* scoped_restore, a simple class for saving and restoring a value + + Copyright (C) 2016-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_SCOPED_RESTORE_H +#define COMMON_SCOPED_RESTORE_H + +/* Base class for scoped_restore_tmpl. */ +class scoped_restore_base +{ +public: + /* This informs the (scoped_restore_tmpl<T>) dtor that you no longer + want the original value restored. */ + void release () const + { m_saved_var = NULL; } + +protected: + scoped_restore_base (void *saved_var) + : m_saved_var (saved_var) + {} + + /* The type-erased saved variable. This is here so that clients can + call release() on a "scoped_restore" local, which is a typedef to + a scoped_restore_base. See below. */ + mutable void *m_saved_var; +}; + +/* A convenience typedef. Users of make_scoped_restore declare the + local RAII object as having this type. */ +typedef const scoped_restore_base &scoped_restore; + +/* An RAII-based object that saves a variable's value, and then + restores it again when this object is destroyed. */ +template<typename T> +class scoped_restore_tmpl : public scoped_restore_base +{ + public: + + /* Create a new scoped_restore object that saves the current value + of *VAR. *VAR will be restored when this scoped_restore object + is destroyed. */ + scoped_restore_tmpl (T *var) + : scoped_restore_base (var), + m_saved_value (*var) + { + } + + /* Create a new scoped_restore object that saves the current value + of *VAR, and sets *VAR to VALUE. *VAR will be restored when this + scoped_restore object is destroyed. This is templated on T2 to + allow passing VALUEs of types convertible to T. + E.g.: T='base'; T2='derived'. */ + template <typename T2> + scoped_restore_tmpl (T *var, T2 value) + : scoped_restore_base (var), + m_saved_value (*var) + { + *var = value; + } + + scoped_restore_tmpl (const scoped_restore_tmpl<T> &other) + : scoped_restore_base {other.m_saved_var}, + m_saved_value (other.m_saved_value) + { + other.m_saved_var = NULL; + } + + ~scoped_restore_tmpl () + { + if (saved_var () != NULL) + *saved_var () = m_saved_value; + } + +private: + /* Return a pointer to the saved variable with its type + restored. */ + T *saved_var () + { return static_cast<T *> (m_saved_var); } + + /* No need for this. It is intentionally not defined anywhere. */ + scoped_restore_tmpl &operator= (const scoped_restore_tmpl &); + + /* The saved value. */ + const T m_saved_value; +}; + +/* Make a scoped_restore. This is useful because it lets template + argument deduction work. */ +template<typename T> +scoped_restore_tmpl<T> make_scoped_restore (T *var) +{ + return scoped_restore_tmpl<T> (var); +} + +/* Make a scoped_restore. This is useful because it lets template + argument deduction work. */ +template<typename T, typename T2> +scoped_restore_tmpl<T> make_scoped_restore (T *var, T2 value) +{ + return scoped_restore_tmpl<T> (var, value); +} + +#endif /* COMMON_SCOPED_RESTORE_H */ diff --git a/gdbsupport/selftest.c b/gdbsupport/selftest.c new file mode 100644 index 0000000..8ab63be --- /dev/null +++ b/gdbsupport/selftest.c @@ -0,0 +1,111 @@ +/* GDB self-testing. + Copyright (C) 2016-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "common-defs.h" +#include "common-exceptions.h" +#include "common-debug.h" +#include "selftest.h" +#include <map> + +namespace selftests +{ +/* All the tests that have been registered. Using an std::map allows keeping + the order of tests stable and easily looking up whether a test name + exists. */ + +static std::map<std::string, std::unique_ptr<selftest>> tests; + +/* A selftest that calls the test function without arguments. */ + +struct simple_selftest : public selftest +{ + simple_selftest (self_test_function *function_) + : function (function_) + {} + + void operator() () const override + { + function (); + } + + self_test_function *function; +}; + +/* See selftest.h. */ + +void +register_test (const std::string &name, selftest *test) +{ + /* Check that no test with this name already exist. */ + gdb_assert (tests.find (name) == tests.end ()); + + tests[name] = std::unique_ptr<selftest> (test); +} + +/* See selftest.h. */ + +void +register_test (const std::string &name, self_test_function *function) +{ + register_test (name, new simple_selftest (function)); +} + +/* See selftest.h. */ + +void +run_tests (const char *filter) +{ + int ran = 0, failed = 0; + + for (const auto &pair : tests) + { + const std::string &name = pair.first; + const std::unique_ptr<selftest> &test = pair.second; + + if (filter != NULL && *filter != '\0' + && name.find (filter) == std::string::npos) + continue; + + try + { + debug_printf (_("Running selftest %s.\n"), name.c_str ()); + ++ran; + (*test) (); + } + catch (const gdb_exception_error &ex) + { + ++failed; + debug_printf ("Self test failed: %s\n", ex.what ()); + } + + reset (); + } + + debug_printf (_("Ran %d unit tests, %d failed\n"), + ran, failed); +} + +/* See selftest.h. */ + +void for_each_selftest (for_each_selftest_ftype func) +{ + for (const auto &pair : tests) + func (pair.first); +} + +} // namespace selftests diff --git a/gdbsupport/selftest.h b/gdbsupport/selftest.h new file mode 100644 index 0000000..1c47fe1 --- /dev/null +++ b/gdbsupport/selftest.h @@ -0,0 +1,73 @@ +/* GDB self-testing. + Copyright (C) 2016-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_SELFTEST_H +#define COMMON_SELFTEST_H + +/* A test is just a function that does some checks and throws an + exception if something has gone wrong. */ + +typedef void self_test_function (void); + +namespace selftests +{ + +/* Interface for the various kinds of selftests. */ + +struct selftest +{ + virtual ~selftest () = default; + virtual void operator() () const = 0; +}; + +/* Register a new self-test. */ + +extern void register_test (const std::string &name, selftest *test); + +/* Register a new self-test. */ + +extern void register_test (const std::string &name, + self_test_function *function); + +/* Run all the self tests. This print a message describing the number + of test and the number of failures. + + If FILTER is not NULL and not empty, only tests with names containing FILTER + will be ran. */ + +extern void run_tests (const char *filter); + +/* Reset GDB or GDBserver's internal state. */ +extern void reset (); + +typedef void for_each_selftest_ftype (const std::string &name); + +/* Call FUNC for each registered selftest. */ + +extern void for_each_selftest (for_each_selftest_ftype func); +} + +/* Check that VALUE is true, and, if not, throw an exception. */ + +#define SELF_CHECK(VALUE) \ + do { \ + if (!(VALUE)) \ + error (_("self-test failed at %s:%d"), __FILE__, __LINE__); \ + } while (0) + +#endif /* COMMON_SELFTEST_H */ diff --git a/gdbsupport/signals-state-save-restore.c b/gdbsupport/signals-state-save-restore.c new file mode 100644 index 0000000..c292d49 --- /dev/null +++ b/gdbsupport/signals-state-save-restore.c @@ -0,0 +1,114 @@ +/* Copyright (C) 2016-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "common-defs.h" +#include "signals-state-save-restore.h" +#include "gdbsupport/gdb-sigmask.h" + +#include <signal.h> + +/* The original signal actions and mask. */ + +#ifdef HAVE_SIGACTION +static struct sigaction original_signal_actions[NSIG]; + +static sigset_t original_signal_mask; +#endif + +/* See signals-state-save-restore.h. */ + +void +save_original_signals_state (bool quiet) +{ +#ifdef HAVE_SIGACTION + int i; + int res; + + res = gdb_sigmask (0, NULL, &original_signal_mask); + if (res == -1) + perror_with_name (("sigprocmask")); + + bool found_preinstalled = false; + + for (i = 1; i < NSIG; i++) + { + struct sigaction *oldact = &original_signal_actions[i]; + + res = sigaction (i, NULL, oldact); + if (res == -1 && errno == EINVAL) + { + /* Some signal numbers in the range are invalid. */ + continue; + } + else if (res == -1) + perror_with_name (("sigaction")); + + /* If we find a custom signal handler already installed, then + this function was called too late. This is a warning instead + of an internal error because this can also happen if you + LD_PRELOAD a library that installs a signal handler early via + __attribute__((constructor)), like libSegFault.so. */ + if (!quiet + && oldact->sa_handler != SIG_DFL + && oldact->sa_handler != SIG_IGN) + { + found_preinstalled = true; + + /* Use raw fprintf here because we're being called in early + startup, before GDB's filtered streams are created. */ + fprintf (stderr, + _("warning: Found custom handler for signal " + "%d (%s) preinstalled.\n"), i, + strsignal (i)); + } + } + + if (found_preinstalled) + { + fprintf (stderr, _("\ +Some signal dispositions inherited from the environment (SIG_DFL/SIG_IGN)\n\ +won't be propagated to spawned programs.\n")); + } +#endif +} + +/* See signals-state-save-restore.h. */ + +void +restore_original_signals_state (void) +{ +#ifdef HAVE_SIGACTION + int i; + int res; + + for (i = 1; i < NSIG; i++) + { + res = sigaction (i, &original_signal_actions[i], NULL); + if (res == -1 && errno == EINVAL) + { + /* Some signal numbers in the range are invalid. */ + continue; + } + else if (res == -1) + perror_with_name (("sigaction")); + } + + res = gdb_sigmask (SIG_SETMASK, &original_signal_mask, NULL); + if (res == -1) + perror_with_name (("sigprocmask")); +#endif +} diff --git a/gdbsupport/signals-state-save-restore.h b/gdbsupport/signals-state-save-restore.h new file mode 100644 index 0000000..8726bf1 --- /dev/null +++ b/gdbsupport/signals-state-save-restore.h @@ -0,0 +1,40 @@ +/* Copyright (C) 2016-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_SIGNALS_STATE_SAVE_RESTORE_H +#define COMMON_SIGNALS_STATE_SAVE_RESTORE_H + +/* Save/restore the signal actions of all signals, and the signal + mask. + + Since the exec family of functions does not reset the signal + disposition of signals set to SIG_IGN, nor does it reset the signal + mask, in order to be transparent, when spawning new child processes + to debug (with "run", etc.), we must reset signal actions and mask + back to what was originally inherited from gdb/gdbserver's parent, + just before execing the target program to debug. */ + +/* Save the signal state of all signals. If !QUIET, warn if we detect + a custom signal handler preinstalled. */ + +extern void save_original_signals_state (bool quiet); + +/* Restore the signal state of all signals. */ + +extern void restore_original_signals_state (void); + +#endif /* COMMON_SIGNALS_STATE_SAVE_RESTORE_H */ diff --git a/gdbsupport/signals.c b/gdbsupport/signals.c new file mode 100644 index 0000000..485e0f0 --- /dev/null +++ b/gdbsupport/signals.c @@ -0,0 +1,653 @@ +/* Target signal translation functions for GDB. + Copyright (C) 1990-2020 Free Software Foundation, Inc. + Contributed by Cygnus Support. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "common-defs.h" + +#ifdef HAVE_SIGNAL_H +#include <signal.h> +#endif + +#include "gdb_signals.h" + +struct gdbarch; + +/* Always use __SIGRTMIN if it's available. SIGRTMIN is the lowest + _available_ realtime signal, not the lowest supported; glibc takes + several for its own use. */ + +#ifndef REALTIME_LO +# if defined(__SIGRTMIN) +# define REALTIME_LO __SIGRTMIN +# define REALTIME_HI (__SIGRTMAX + 1) +# elif defined(SIGRTMIN) +# define REALTIME_LO SIGRTMIN +# define REALTIME_HI (SIGRTMAX + 1) +# endif +#endif + +/* This table must match in order and size the signals in enum + gdb_signal. */ + +static const struct { + const char *symbol; + const char *name; + const char *string; + } signals [] = +{ +#define SET(symbol, constant, name, string) { #symbol, name, string }, +#include "gdb/signals.def" +#undef SET +}; + +const char * +gdb_signal_to_symbol_string (enum gdb_signal sig) +{ + gdb_assert ((int) sig >= GDB_SIGNAL_FIRST && (int) sig <= GDB_SIGNAL_LAST); + + return signals[sig].symbol; +} + +/* Return the string for a signal. */ +const char * +gdb_signal_to_string (enum gdb_signal sig) +{ + if ((int) sig >= GDB_SIGNAL_FIRST && (int) sig <= GDB_SIGNAL_LAST) + return signals[sig].string; + else + return signals[GDB_SIGNAL_UNKNOWN].string; +} + +/* Return the name for a signal. */ +const char * +gdb_signal_to_name (enum gdb_signal sig) +{ + if ((int) sig >= GDB_SIGNAL_FIRST && (int) sig <= GDB_SIGNAL_LAST + && signals[sig].name != NULL) + return signals[sig].name; + else + /* I think the code which prints this will always print it along + with the string, so no need to be verbose (very old comment). */ + return "?"; +} + +/* Given a name, return its signal. */ +enum gdb_signal +gdb_signal_from_name (const char *name) +{ + enum gdb_signal sig; + + /* It's possible we also should allow "SIGCLD" as well as "SIGCHLD" + for GDB_SIGNAL_SIGCHLD. SIGIOT, on the other hand, is more + questionable; seems like by now people should call it SIGABRT + instead. */ + + /* This ugly cast brought to you by the native VAX compiler. */ + for (sig = GDB_SIGNAL_HUP; + sig < GDB_SIGNAL_LAST; + sig = (enum gdb_signal) ((int) sig + 1)) + if (signals[sig].name != NULL + && strcmp (name, signals[sig].name) == 0) + return sig; + return GDB_SIGNAL_UNKNOWN; +} + +/* The following functions are to help certain targets deal + with the signal/waitstatus stuff. They could just as well be in + a file called native-utils.c or unixwaitstatus-utils.c or whatever. */ + +/* Convert host signal to our signals. */ +enum gdb_signal +gdb_signal_from_host (int hostsig) +{ + /* A switch statement would make sense but would require special + kludges to deal with the cases where more than one signal has the + same number. Signals are ordered ANSI-standard signals first, + other signals second, with signals in each block ordered by their + numerical values on a typical POSIX platform. */ + + if (hostsig == 0) + return GDB_SIGNAL_0; + + /* SIGINT, SIGILL, SIGABRT, SIGFPE, SIGSEGV and SIGTERM + are ANSI-standard signals and are always available. */ + if (hostsig == SIGINT) + return GDB_SIGNAL_INT; + if (hostsig == SIGILL) + return GDB_SIGNAL_ILL; + if (hostsig == SIGABRT) + return GDB_SIGNAL_ABRT; + if (hostsig == SIGFPE) + return GDB_SIGNAL_FPE; + if (hostsig == SIGSEGV) + return GDB_SIGNAL_SEGV; + if (hostsig == SIGTERM) + return GDB_SIGNAL_TERM; + + /* All other signals need preprocessor conditionals. */ +#if defined (SIGHUP) + if (hostsig == SIGHUP) + return GDB_SIGNAL_HUP; +#endif +#if defined (SIGQUIT) + if (hostsig == SIGQUIT) + return GDB_SIGNAL_QUIT; +#endif +#if defined (SIGTRAP) + if (hostsig == SIGTRAP) + return GDB_SIGNAL_TRAP; +#endif +#if defined (SIGEMT) + if (hostsig == SIGEMT) + return GDB_SIGNAL_EMT; +#endif +#if defined (SIGKILL) + if (hostsig == SIGKILL) + return GDB_SIGNAL_KILL; +#endif +#if defined (SIGBUS) + if (hostsig == SIGBUS) + return GDB_SIGNAL_BUS; +#endif +#if defined (SIGSYS) + if (hostsig == SIGSYS) + return GDB_SIGNAL_SYS; +#endif +#if defined (SIGPIPE) + if (hostsig == SIGPIPE) + return GDB_SIGNAL_PIPE; +#endif +#if defined (SIGALRM) + if (hostsig == SIGALRM) + return GDB_SIGNAL_ALRM; +#endif +#if defined (SIGUSR1) + if (hostsig == SIGUSR1) + return GDB_SIGNAL_USR1; +#endif +#if defined (SIGUSR2) + if (hostsig == SIGUSR2) + return GDB_SIGNAL_USR2; +#endif +#if defined (SIGCLD) + if (hostsig == SIGCLD) + return GDB_SIGNAL_CHLD; +#endif +#if defined (SIGCHLD) + if (hostsig == SIGCHLD) + return GDB_SIGNAL_CHLD; +#endif +#if defined (SIGPWR) + if (hostsig == SIGPWR) + return GDB_SIGNAL_PWR; +#endif +#if defined (SIGWINCH) + if (hostsig == SIGWINCH) + return GDB_SIGNAL_WINCH; +#endif +#if defined (SIGURG) + if (hostsig == SIGURG) + return GDB_SIGNAL_URG; +#endif +#if defined (SIGIO) + if (hostsig == SIGIO) + return GDB_SIGNAL_IO; +#endif +#if defined (SIGPOLL) + if (hostsig == SIGPOLL) + return GDB_SIGNAL_POLL; +#endif +#if defined (SIGSTOP) + if (hostsig == SIGSTOP) + return GDB_SIGNAL_STOP; +#endif +#if defined (SIGTSTP) + if (hostsig == SIGTSTP) + return GDB_SIGNAL_TSTP; +#endif +#if defined (SIGCONT) + if (hostsig == SIGCONT) + return GDB_SIGNAL_CONT; +#endif +#if defined (SIGTTIN) + if (hostsig == SIGTTIN) + return GDB_SIGNAL_TTIN; +#endif +#if defined (SIGTTOU) + if (hostsig == SIGTTOU) + return GDB_SIGNAL_TTOU; +#endif +#if defined (SIGVTALRM) + if (hostsig == SIGVTALRM) + return GDB_SIGNAL_VTALRM; +#endif +#if defined (SIGPROF) + if (hostsig == SIGPROF) + return GDB_SIGNAL_PROF; +#endif +#if defined (SIGXCPU) + if (hostsig == SIGXCPU) + return GDB_SIGNAL_XCPU; +#endif +#if defined (SIGXFSZ) + if (hostsig == SIGXFSZ) + return GDB_SIGNAL_XFSZ; +#endif +#if defined (SIGWIND) + if (hostsig == SIGWIND) + return GDB_SIGNAL_WIND; +#endif +#if defined (SIGPHONE) + if (hostsig == SIGPHONE) + return GDB_SIGNAL_PHONE; +#endif +#if defined (SIGLOST) + if (hostsig == SIGLOST) + return GDB_SIGNAL_LOST; +#endif +#if defined (SIGWAITING) + if (hostsig == SIGWAITING) + return GDB_SIGNAL_WAITING; +#endif +#if defined (SIGCANCEL) + if (hostsig == SIGCANCEL) + return GDB_SIGNAL_CANCEL; +#endif +#if defined (SIGLWP) + if (hostsig == SIGLWP) + return GDB_SIGNAL_LWP; +#endif +#if defined (SIGDANGER) + if (hostsig == SIGDANGER) + return GDB_SIGNAL_DANGER; +#endif +#if defined (SIGGRANT) + if (hostsig == SIGGRANT) + return GDB_SIGNAL_GRANT; +#endif +#if defined (SIGRETRACT) + if (hostsig == SIGRETRACT) + return GDB_SIGNAL_RETRACT; +#endif +#if defined (SIGMSG) + if (hostsig == SIGMSG) + return GDB_SIGNAL_MSG; +#endif +#if defined (SIGSOUND) + if (hostsig == SIGSOUND) + return GDB_SIGNAL_SOUND; +#endif +#if defined (SIGSAK) + if (hostsig == SIGSAK) + return GDB_SIGNAL_SAK; +#endif +#if defined (SIGPRIO) + if (hostsig == SIGPRIO) + return GDB_SIGNAL_PRIO; +#endif + + /* Mach exceptions. Assumes that the values for EXC_ are positive! */ +#if defined (EXC_BAD_ACCESS) && defined (_NSIG) + if (hostsig == _NSIG + EXC_BAD_ACCESS) + return GDB_EXC_BAD_ACCESS; +#endif +#if defined (EXC_BAD_INSTRUCTION) && defined (_NSIG) + if (hostsig == _NSIG + EXC_BAD_INSTRUCTION) + return GDB_EXC_BAD_INSTRUCTION; +#endif +#if defined (EXC_ARITHMETIC) && defined (_NSIG) + if (hostsig == _NSIG + EXC_ARITHMETIC) + return GDB_EXC_ARITHMETIC; +#endif +#if defined (EXC_EMULATION) && defined (_NSIG) + if (hostsig == _NSIG + EXC_EMULATION) + return GDB_EXC_EMULATION; +#endif +#if defined (EXC_SOFTWARE) && defined (_NSIG) + if (hostsig == _NSIG + EXC_SOFTWARE) + return GDB_EXC_SOFTWARE; +#endif +#if defined (EXC_BREAKPOINT) && defined (_NSIG) + if (hostsig == _NSIG + EXC_BREAKPOINT) + return GDB_EXC_BREAKPOINT; +#endif + +#if defined (SIGINFO) + if (hostsig == SIGINFO) + return GDB_SIGNAL_INFO; +#endif +#if defined (SIGLIBRT) + if (hostsig == SIGLIBRT) + return GDB_SIGNAL_LIBRT; +#endif + +#if defined (REALTIME_LO) + if (hostsig >= REALTIME_LO && hostsig < REALTIME_HI) + { + /* This block of GDB_SIGNAL_REALTIME value is in order. */ + if (33 <= hostsig && hostsig <= 63) + return (enum gdb_signal) + (hostsig - 33 + (int) GDB_SIGNAL_REALTIME_33); + else if (hostsig == 32) + return GDB_SIGNAL_REALTIME_32; + else if (64 <= hostsig && hostsig <= 127) + return (enum gdb_signal) + (hostsig - 64 + (int) GDB_SIGNAL_REALTIME_64); + else + error (_("GDB bug: target.c (gdb_signal_from_host): " + "unrecognized real-time signal")); + } +#endif + + return GDB_SIGNAL_UNKNOWN; +} + +/* Convert a OURSIG (an enum gdb_signal) to the form used by the + target operating system (refered to as the ``host'') or zero if the + equivalent host signal is not available. Set/clear OURSIG_OK + accordingly. */ + +static int +do_gdb_signal_to_host (enum gdb_signal oursig, + int *oursig_ok) +{ + int retsig; + /* Silence the 'not used' warning, for targets that + do not support signals. */ + (void) retsig; + + /* Signals are ordered ANSI-standard signals first, other signals + second, with signals in each block ordered by their numerical + values on a typical POSIX platform. */ + + *oursig_ok = 1; + switch (oursig) + { + case GDB_SIGNAL_0: + return 0; + + /* SIGINT, SIGILL, SIGABRT, SIGFPE, SIGSEGV and SIGTERM + are ANSI-standard signals and are always available. */ + case GDB_SIGNAL_INT: + return SIGINT; + case GDB_SIGNAL_ILL: + return SIGILL; + case GDB_SIGNAL_ABRT: + return SIGABRT; + case GDB_SIGNAL_FPE: + return SIGFPE; + case GDB_SIGNAL_SEGV: + return SIGSEGV; + case GDB_SIGNAL_TERM: + return SIGTERM; + + /* All other signals need preprocessor conditionals. */ +#if defined (SIGHUP) + case GDB_SIGNAL_HUP: + return SIGHUP; +#endif +#if defined (SIGQUIT) + case GDB_SIGNAL_QUIT: + return SIGQUIT; +#endif +#if defined (SIGTRAP) + case GDB_SIGNAL_TRAP: + return SIGTRAP; +#endif +#if defined (SIGEMT) + case GDB_SIGNAL_EMT: + return SIGEMT; +#endif +#if defined (SIGKILL) + case GDB_SIGNAL_KILL: + return SIGKILL; +#endif +#if defined (SIGBUS) + case GDB_SIGNAL_BUS: + return SIGBUS; +#endif +#if defined (SIGSYS) + case GDB_SIGNAL_SYS: + return SIGSYS; +#endif +#if defined (SIGPIPE) + case GDB_SIGNAL_PIPE: + return SIGPIPE; +#endif +#if defined (SIGALRM) + case GDB_SIGNAL_ALRM: + return SIGALRM; +#endif +#if defined (SIGUSR1) + case GDB_SIGNAL_USR1: + return SIGUSR1; +#endif +#if defined (SIGUSR2) + case GDB_SIGNAL_USR2: + return SIGUSR2; +#endif +#if defined (SIGCHLD) || defined (SIGCLD) + case GDB_SIGNAL_CHLD: +#if defined (SIGCHLD) + return SIGCHLD; +#else + return SIGCLD; +#endif +#endif /* SIGCLD or SIGCHLD */ +#if defined (SIGPWR) + case GDB_SIGNAL_PWR: + return SIGPWR; +#endif +#if defined (SIGWINCH) + case GDB_SIGNAL_WINCH: + return SIGWINCH; +#endif +#if defined (SIGURG) + case GDB_SIGNAL_URG: + return SIGURG; +#endif +#if defined (SIGIO) + case GDB_SIGNAL_IO: + return SIGIO; +#endif +#if defined (SIGPOLL) + case GDB_SIGNAL_POLL: + return SIGPOLL; +#endif +#if defined (SIGSTOP) + case GDB_SIGNAL_STOP: + return SIGSTOP; +#endif +#if defined (SIGTSTP) + case GDB_SIGNAL_TSTP: + return SIGTSTP; +#endif +#if defined (SIGCONT) + case GDB_SIGNAL_CONT: + return SIGCONT; +#endif +#if defined (SIGTTIN) + case GDB_SIGNAL_TTIN: + return SIGTTIN; +#endif +#if defined (SIGTTOU) + case GDB_SIGNAL_TTOU: + return SIGTTOU; +#endif +#if defined (SIGVTALRM) + case GDB_SIGNAL_VTALRM: + return SIGVTALRM; +#endif +#if defined (SIGPROF) + case GDB_SIGNAL_PROF: + return SIGPROF; +#endif +#if defined (SIGXCPU) + case GDB_SIGNAL_XCPU: + return SIGXCPU; +#endif +#if defined (SIGXFSZ) + case GDB_SIGNAL_XFSZ: + return SIGXFSZ; +#endif +#if defined (SIGWIND) + case GDB_SIGNAL_WIND: + return SIGWIND; +#endif +#if defined (SIGPHONE) + case GDB_SIGNAL_PHONE: + return SIGPHONE; +#endif +#if defined (SIGLOST) + case GDB_SIGNAL_LOST: + return SIGLOST; +#endif +#if defined (SIGWAITING) + case GDB_SIGNAL_WAITING: + return SIGWAITING; +#endif +#if defined (SIGCANCEL) + case GDB_SIGNAL_CANCEL: + return SIGCANCEL; +#endif +#if defined (SIGLWP) + case GDB_SIGNAL_LWP: + return SIGLWP; +#endif +#if defined (SIGDANGER) + case GDB_SIGNAL_DANGER: + return SIGDANGER; +#endif +#if defined (SIGGRANT) + case GDB_SIGNAL_GRANT: + return SIGGRANT; +#endif +#if defined (SIGRETRACT) + case GDB_SIGNAL_RETRACT: + return SIGRETRACT; +#endif +#if defined (SIGMSG) + case GDB_SIGNAL_MSG: + return SIGMSG; +#endif +#if defined (SIGSOUND) + case GDB_SIGNAL_SOUND: + return SIGSOUND; +#endif +#if defined (SIGSAK) + case GDB_SIGNAL_SAK: + return SIGSAK; +#endif +#if defined (SIGPRIO) + case GDB_SIGNAL_PRIO: + return SIGPRIO; +#endif + + /* Mach exceptions. Assumes that the values for EXC_ are positive! */ +#if defined (EXC_BAD_ACCESS) && defined (_NSIG) + case GDB_EXC_BAD_ACCESS: + return _NSIG + EXC_BAD_ACCESS; +#endif +#if defined (EXC_BAD_INSTRUCTION) && defined (_NSIG) + case GDB_EXC_BAD_INSTRUCTION: + return _NSIG + EXC_BAD_INSTRUCTION; +#endif +#if defined (EXC_ARITHMETIC) && defined (_NSIG) + case GDB_EXC_ARITHMETIC: + return _NSIG + EXC_ARITHMETIC; +#endif +#if defined (EXC_EMULATION) && defined (_NSIG) + case GDB_EXC_EMULATION: + return _NSIG + EXC_EMULATION; +#endif +#if defined (EXC_SOFTWARE) && defined (_NSIG) + case GDB_EXC_SOFTWARE: + return _NSIG + EXC_SOFTWARE; +#endif +#if defined (EXC_BREAKPOINT) && defined (_NSIG) + case GDB_EXC_BREAKPOINT: + return _NSIG + EXC_BREAKPOINT; +#endif + +#if defined (SIGINFO) + case GDB_SIGNAL_INFO: + return SIGINFO; +#endif +#if defined (SIGLIBRT) + case GDB_SIGNAL_LIBRT: + return SIGLIBRT; +#endif + + default: +#if defined (REALTIME_LO) + retsig = 0; + + if (oursig >= GDB_SIGNAL_REALTIME_33 + && oursig <= GDB_SIGNAL_REALTIME_63) + { + /* This block of signals is continuous, and + GDB_SIGNAL_REALTIME_33 is 33 by definition. */ + retsig = (int) oursig - (int) GDB_SIGNAL_REALTIME_33 + 33; + } + else if (oursig == GDB_SIGNAL_REALTIME_32) + { + /* GDB_SIGNAL_REALTIME_32 isn't contiguous with + GDB_SIGNAL_REALTIME_33. It is 32 by definition. */ + retsig = 32; + } + else if (oursig >= GDB_SIGNAL_REALTIME_64 + && oursig <= GDB_SIGNAL_REALTIME_127) + { + /* This block of signals is continuous, and + GDB_SIGNAL_REALTIME_64 is 64 by definition. */ + retsig = (int) oursig - (int) GDB_SIGNAL_REALTIME_64 + 64; + } + + if (retsig >= REALTIME_LO && retsig < REALTIME_HI) + return retsig; +#endif + + *oursig_ok = 0; + return 0; + } +} + +int +gdb_signal_to_host_p (enum gdb_signal oursig) +{ + int oursig_ok; + do_gdb_signal_to_host (oursig, &oursig_ok); + return oursig_ok; +} + +int +gdb_signal_to_host (enum gdb_signal oursig) +{ + int oursig_ok; + int targ_signo = do_gdb_signal_to_host (oursig, &oursig_ok); + if (!oursig_ok) + { + /* The user might be trying to do "signal SIGSAK" where this system + doesn't have SIGSAK. */ + warning (_("Signal %s does not exist on this system."), + gdb_signal_to_name (oursig)); + return 0; + } + else + return targ_signo; +} diff --git a/gdbsupport/symbol.h b/gdbsupport/symbol.h new file mode 100644 index 0000000..3cc3adf --- /dev/null +++ b/gdbsupport/symbol.h @@ -0,0 +1,37 @@ +/* Declarations of common symbol functions. + + Copyright (C) 2014-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_SYMBOL_H +#define COMMON_SYMBOL_H + +struct objfile; + +/* Find a symbol that matches NAME. Limit the search to OBJFILE if + OBJFILE is non-NULL and the implementation supports limiting the + search to specific object files. NAME may be mangled or demangled. + If a match is found, store the matching symbol's address in ADDR + and return zero. Returns nonzero if no symbol matching NAME is + found. Raise an exception if OBJFILE is non-NULL and the + implementation does not support limiting searches to specific + object files. This function must be provided by the client. */ + +extern int find_minimal_symbol_address (const char *name, CORE_ADDR *addr, + struct objfile *objfile); + +#endif /* COMMON_SYMBOL_H */ diff --git a/gdbsupport/tdesc.c b/gdbsupport/tdesc.c new file mode 100644 index 0000000..aaea8e0 --- /dev/null +++ b/gdbsupport/tdesc.c @@ -0,0 +1,401 @@ +/* Target description support for GDB. + + Copyright (C) 2018-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "common-defs.h" +#include "gdbsupport/tdesc.h" + +tdesc_reg::tdesc_reg (struct tdesc_feature *feature, const std::string &name_, + int regnum, int save_restore_, const char *group_, + int bitsize_, const char *type_) + : name (name_), target_regnum (regnum), + save_restore (save_restore_), + group (group_ != NULL ? group_ : ""), + bitsize (bitsize_), + type (type_ != NULL ? type_ : "<unknown>") +{ + /* If the register's type is target-defined, look it up now. We may not + have easy access to the containing feature when we want it later. */ + tdesc_type = tdesc_named_type (feature, type.c_str ()); +} + +/* Predefined types. */ +static tdesc_type_builtin tdesc_predefined_types[] = +{ + { "bool", TDESC_TYPE_BOOL }, + { "int8", TDESC_TYPE_INT8 }, + { "int16", TDESC_TYPE_INT16 }, + { "int32", TDESC_TYPE_INT32 }, + { "int64", TDESC_TYPE_INT64 }, + { "int128", TDESC_TYPE_INT128 }, + { "uint8", TDESC_TYPE_UINT8 }, + { "uint16", TDESC_TYPE_UINT16 }, + { "uint32", TDESC_TYPE_UINT32 }, + { "uint64", TDESC_TYPE_UINT64 }, + { "uint128", TDESC_TYPE_UINT128 }, + { "code_ptr", TDESC_TYPE_CODE_PTR }, + { "data_ptr", TDESC_TYPE_DATA_PTR }, + { "ieee_half", TDESC_TYPE_IEEE_HALF }, + { "ieee_single", TDESC_TYPE_IEEE_SINGLE }, + { "ieee_double", TDESC_TYPE_IEEE_DOUBLE }, + { "arm_fpa_ext", TDESC_TYPE_ARM_FPA_EXT }, + { "i387_ext", TDESC_TYPE_I387_EXT } +}; + +void tdesc_feature::accept (tdesc_element_visitor &v) const +{ + v.visit_pre (this); + + for (const tdesc_type_up &type : types) + type->accept (v); + + for (const tdesc_reg_up ® : registers) + reg->accept (v); + + v.visit_post (this); +} + +bool tdesc_feature::operator== (const tdesc_feature &other) const +{ + if (name != other.name) + return false; + + if (registers.size () != other.registers.size ()) + return false; + + for (int ix = 0; ix < registers.size (); ix++) + { + const tdesc_reg_up ®1 = registers[ix]; + const tdesc_reg_up ®2 = other.registers[ix]; + + if (reg1 != reg2 && *reg1 != *reg2) + return false; + } + + if (types.size () != other.types.size ()) + return false; + + for (int ix = 0; ix < types.size (); ix++) + { + const tdesc_type_up &type1 = types[ix]; + const tdesc_type_up &type2 = other.types[ix]; + + if (type1 != type2 && *type1 != *type2) + return false; + } + + return true; +} + +/* Lookup a predefined type. */ + +static struct tdesc_type * +tdesc_predefined_type (enum tdesc_type_kind kind) +{ + for (int ix = 0; ix < ARRAY_SIZE (tdesc_predefined_types); ix++) + if (tdesc_predefined_types[ix].kind == kind) + return &tdesc_predefined_types[ix]; + + gdb_assert_not_reached ("bad predefined tdesc type"); +} + +/* See gdbsupport/tdesc.h. */ + +struct tdesc_type * +tdesc_named_type (const struct tdesc_feature *feature, const char *id) +{ + /* First try target-defined types. */ + for (const tdesc_type_up &type : feature->types) + if (type->name == id) + return type.get (); + + /* Next try the predefined types. */ + for (int ix = 0; ix < ARRAY_SIZE (tdesc_predefined_types); ix++) + if (tdesc_predefined_types[ix].name == id) + return &tdesc_predefined_types[ix]; + + return NULL; +} + +/* See gdbsupport/tdesc.h. */ + +void +tdesc_create_reg (struct tdesc_feature *feature, const char *name, + int regnum, int save_restore, const char *group, + int bitsize, const char *type) +{ + tdesc_reg *reg = new tdesc_reg (feature, name, regnum, save_restore, + group, bitsize, type); + + feature->registers.emplace_back (reg); +} + +/* See gdbsupport/tdesc.h. */ + +struct tdesc_type * +tdesc_create_vector (struct tdesc_feature *feature, const char *name, + struct tdesc_type *field_type, int count) +{ + tdesc_type_vector *type = new tdesc_type_vector (name, field_type, count); + feature->types.emplace_back (type); + + return type; +} + +/* See gdbsupport/tdesc.h. */ + +tdesc_type_with_fields * +tdesc_create_struct (struct tdesc_feature *feature, const char *name) +{ + tdesc_type_with_fields *type + = new tdesc_type_with_fields (name, TDESC_TYPE_STRUCT); + feature->types.emplace_back (type); + + return type; +} + +/* See gdbsupport/tdesc.h. */ + +void +tdesc_set_struct_size (tdesc_type_with_fields *type, int size) +{ + gdb_assert (type->kind == TDESC_TYPE_STRUCT); + gdb_assert (size > 0); + type->size = size; +} + +/* See gdbsupport/tdesc.h. */ + +tdesc_type_with_fields * +tdesc_create_union (struct tdesc_feature *feature, const char *name) +{ + tdesc_type_with_fields *type + = new tdesc_type_with_fields (name, TDESC_TYPE_UNION); + feature->types.emplace_back (type); + + return type; +} + +/* See gdbsupport/tdesc.h. */ + +tdesc_type_with_fields * +tdesc_create_flags (struct tdesc_feature *feature, const char *name, + int size) +{ + gdb_assert (size > 0); + + tdesc_type_with_fields *type + = new tdesc_type_with_fields (name, TDESC_TYPE_FLAGS, size); + feature->types.emplace_back (type); + + return type; +} + +/* See gdbsupport/tdesc.h. */ + +tdesc_type_with_fields * +tdesc_create_enum (struct tdesc_feature *feature, const char *name, + int size) +{ + gdb_assert (size > 0); + + tdesc_type_with_fields *type + = new tdesc_type_with_fields (name, TDESC_TYPE_ENUM, size); + feature->types.emplace_back (type); + + return type; +} + +/* See gdbsupport/tdesc.h. */ + +void +tdesc_add_field (tdesc_type_with_fields *type, const char *field_name, + struct tdesc_type *field_type) +{ + gdb_assert (type->kind == TDESC_TYPE_UNION + || type->kind == TDESC_TYPE_STRUCT); + + /* Initialize start and end so we know this is not a bit-field + when we print-c-tdesc. */ + type->fields.emplace_back (field_name, field_type, -1, -1); +} + +/* See gdbsupport/tdesc.h. */ + +void +tdesc_add_typed_bitfield (tdesc_type_with_fields *type, const char *field_name, + int start, int end, struct tdesc_type *field_type) +{ + gdb_assert (type->kind == TDESC_TYPE_STRUCT + || type->kind == TDESC_TYPE_FLAGS); + gdb_assert (start >= 0 && end >= start); + + type->fields.emplace_back (field_name, field_type, start, end); +} + +/* See gdbsupport/tdesc.h. */ + +void +tdesc_add_bitfield (tdesc_type_with_fields *type, const char *field_name, + int start, int end) +{ + struct tdesc_type *field_type; + + gdb_assert (start >= 0 && end >= start); + + if (type->size > 4) + field_type = tdesc_predefined_type (TDESC_TYPE_UINT64); + else + field_type = tdesc_predefined_type (TDESC_TYPE_UINT32); + + tdesc_add_typed_bitfield (type, field_name, start, end, field_type); +} + +/* See gdbsupport/tdesc.h. */ + +void +tdesc_add_flag (tdesc_type_with_fields *type, int start, + const char *flag_name) +{ + gdb_assert (type->kind == TDESC_TYPE_FLAGS + || type->kind == TDESC_TYPE_STRUCT); + + type->fields.emplace_back (flag_name, + tdesc_predefined_type (TDESC_TYPE_BOOL), + start, start); +} + +/* See gdbsupport/tdesc.h. */ + +void +tdesc_add_enum_value (tdesc_type_with_fields *type, int value, + const char *name) +{ + gdb_assert (type->kind == TDESC_TYPE_ENUM); + type->fields.emplace_back (name, + tdesc_predefined_type (TDESC_TYPE_INT32), + value, -1); +} + +void print_xml_feature::visit_pre (const tdesc_feature *e) +{ + string_appendf (*m_buffer, "<feature name=\"%s\">\n", e->name.c_str ()); +} + +void print_xml_feature::visit_post (const tdesc_feature *e) +{ + string_appendf (*m_buffer, "</feature>\n"); +} + +void print_xml_feature::visit (const tdesc_type_builtin *t) +{ + error (_("xml output is not supported for type \"%s\"."), t->name.c_str ()); +} + +void print_xml_feature::visit (const tdesc_type_vector *t) +{ + string_appendf (*m_buffer, "<vector id=\"%s\" type=\"%s\" count=\"%d\"/>\n", + t->name.c_str (), t->element_type->name.c_str (), t->count); +} + +void print_xml_feature::visit (const tdesc_type_with_fields *t) +{ + const static char *types[] = { "struct", "union", "flags", "enum" }; + + gdb_assert (t->kind >= TDESC_TYPE_STRUCT && t->kind <= TDESC_TYPE_ENUM); + + string_appendf (*m_buffer, + "<%s id=\"%s\"", types[t->kind - TDESC_TYPE_STRUCT], + t->name.c_str ()); + + switch (t->kind) + { + case TDESC_TYPE_STRUCT: + case TDESC_TYPE_FLAGS: + if (t->size > 0) + string_appendf (*m_buffer, " size=\"%d\"", t->size); + string_appendf (*m_buffer, ">\n"); + + for (const tdesc_type_field &f : t->fields) + { + string_appendf (*m_buffer, " <field name=\"%s\" ", f.name.c_str ()); + if (f.start == -1) + string_appendf (*m_buffer, "type=\"%s\"/>\n", + f.type->name.c_str ()); + else + string_appendf (*m_buffer, "start=\"%d\" end=\"%d\"/>\n", f.start, + f.end); + } + break; + + case TDESC_TYPE_ENUM: + string_appendf (*m_buffer, ">\n"); + for (const tdesc_type_field &f : t->fields) + string_appendf (*m_buffer, " <field name=\"%s\" start=\"%d\"/>\n", + f.name.c_str (), f.start); + break; + + case TDESC_TYPE_UNION: + string_appendf (*m_buffer, ">\n"); + for (const tdesc_type_field &f : t->fields) + string_appendf (*m_buffer, " <field name=\"%s\" type=\"%s\"/>\n", + f.name.c_str (), f.type->name.c_str ()); + break; + + default: + error (_("xml output is not supported for type \"%s\"."), + t->name.c_str ()); + } + + string_appendf (*m_buffer, "</%s>\n", types[t->kind - TDESC_TYPE_STRUCT]); +} + +void print_xml_feature::visit (const tdesc_reg *r) +{ + string_appendf (*m_buffer, + "<reg name=\"%s\" bitsize=\"%d\" type=\"%s\" regnum=\"%ld\"", + r->name.c_str (), r->bitsize, r->type.c_str (), + r->target_regnum); + + if (r->group.length () > 0) + string_appendf (*m_buffer, " group=\"%s\"", r->group.c_str ()); + + if (r->save_restore == 0) + string_appendf (*m_buffer, " save-restore=\"no\""); + + string_appendf (*m_buffer, "/>\n"); +} + +void print_xml_feature::visit_pre (const target_desc *e) +{ +#ifndef IN_PROCESS_AGENT + string_appendf (*m_buffer, "<?xml version=\"1.0\"?>\n"); + string_appendf (*m_buffer, "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">\n"); + string_appendf (*m_buffer, "<target>\n<architecture>%s</architecture>\n", + tdesc_architecture_name (e)); + + const char *osabi = tdesc_osabi_name (e); + if (osabi != nullptr) + string_appendf (*m_buffer, "<osabi>%s</osabi>", osabi); +#endif +} + +void print_xml_feature::visit_post (const target_desc *e) +{ + string_appendf (*m_buffer, "</target>\n"); +} diff --git a/gdbsupport/tdesc.h b/gdbsupport/tdesc.h new file mode 100644 index 0000000..3b1f1f5 --- /dev/null +++ b/gdbsupport/tdesc.h @@ -0,0 +1,408 @@ +/* Copyright (C) 2006-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_TDESC_H +#define COMMON_TDESC_H + +struct tdesc_feature; +struct tdesc_type; +struct tdesc_type_builtin; +struct tdesc_type_vector; +struct tdesc_type_with_fields; +struct tdesc_reg; +struct target_desc; + +/* The interface to visit different elements of target description. */ + +class tdesc_element_visitor +{ +public: + virtual void visit_pre (const target_desc *e) + {} + + virtual void visit_post (const target_desc *e) + {} + + virtual void visit_pre (const tdesc_feature *e) + {} + + virtual void visit_post (const tdesc_feature *e) + {} + + virtual void visit (const tdesc_type_builtin *e) + {} + + virtual void visit (const tdesc_type_vector *e) + {} + + virtual void visit (const tdesc_type_with_fields *e) + {} + + virtual void visit (const tdesc_reg *e) + {} +}; + +class tdesc_element +{ +public: + virtual void accept (tdesc_element_visitor &v) const = 0; +}; + +/* An individual register from a target description. */ + +struct tdesc_reg : tdesc_element +{ + tdesc_reg (struct tdesc_feature *feature, const std::string &name_, + int regnum, int save_restore_, const char *group_, + int bitsize_, const char *type_); + + virtual ~tdesc_reg () = default; + + DISABLE_COPY_AND_ASSIGN (tdesc_reg); + + /* The name of this register. In standard features, it may be + recognized by the architecture support code, or it may be purely + for the user. */ + std::string name; + + /* The register number used by this target to refer to this + register. This is used for remote p/P packets and to determine + the ordering of registers in the remote g/G packets. */ + long target_regnum; + + /* 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, or empty + if the group should be automatically determined from the + register's type. 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. Currently other + strings are ignored (treated as empty). */ + std::string group; + + /* The size of the register, in bits. */ + int bitsize; + + /* The type of the register. This string corresponds to either + a named type from the target description or a predefined + type from GDB. */ + std::string type; + + /* The target-described type corresponding to TYPE, if found. */ + struct tdesc_type *tdesc_type; + + void accept (tdesc_element_visitor &v) const override + { + v.visit (this); + } + + bool operator== (const tdesc_reg &other) const + { + return (name == other.name + && target_regnum == other.target_regnum + && save_restore == other.save_restore + && bitsize == other.bitsize + && group == other.group + && type == other.type); + } + + bool operator!= (const tdesc_reg &other) const + { + return !(*this == other); + } +}; + +typedef std::unique_ptr<tdesc_reg> tdesc_reg_up; + +enum tdesc_type_kind +{ + /* Predefined types. */ + TDESC_TYPE_BOOL, + TDESC_TYPE_INT8, + TDESC_TYPE_INT16, + TDESC_TYPE_INT32, + TDESC_TYPE_INT64, + TDESC_TYPE_INT128, + TDESC_TYPE_UINT8, + TDESC_TYPE_UINT16, + TDESC_TYPE_UINT32, + TDESC_TYPE_UINT64, + TDESC_TYPE_UINT128, + TDESC_TYPE_CODE_PTR, + TDESC_TYPE_DATA_PTR, + TDESC_TYPE_IEEE_HALF, + TDESC_TYPE_IEEE_SINGLE, + TDESC_TYPE_IEEE_DOUBLE, + TDESC_TYPE_ARM_FPA_EXT, + TDESC_TYPE_I387_EXT, + + /* Types defined by a target feature. */ + TDESC_TYPE_VECTOR, + TDESC_TYPE_STRUCT, + TDESC_TYPE_UNION, + TDESC_TYPE_FLAGS, + TDESC_TYPE_ENUM +}; + +struct tdesc_type : tdesc_element +{ + tdesc_type (const std::string &name_, enum tdesc_type_kind kind_) + : name (name_), kind (kind_) + {} + + virtual ~tdesc_type () = default; + + DISABLE_COPY_AND_ASSIGN (tdesc_type); + + /* The name of this type. */ + std::string name; + + /* Identify the kind of this type. */ + enum tdesc_type_kind kind; + + bool operator== (const tdesc_type &other) const + { + return name == other.name && kind == other.kind; + } + + bool operator!= (const tdesc_type &other) const + { + return !(*this == other); + } +}; + +typedef std::unique_ptr<tdesc_type> tdesc_type_up; + +struct tdesc_type_builtin : tdesc_type +{ + tdesc_type_builtin (const std::string &name, enum tdesc_type_kind kind) + : tdesc_type (name, kind) + {} + + void accept (tdesc_element_visitor &v) const override + { + v.visit (this); + } +}; + +/* tdesc_type for vector types. */ + +struct tdesc_type_vector : tdesc_type +{ + tdesc_type_vector (const std::string &name, tdesc_type *element_type_, + int count_) + : tdesc_type (name, TDESC_TYPE_VECTOR), + element_type (element_type_), count (count_) + {} + + void accept (tdesc_element_visitor &v) const override + { + v.visit (this); + } + + struct tdesc_type *element_type; + int count; +}; + +/* A named type from a target description. */ + +struct tdesc_type_field +{ + tdesc_type_field (const std::string &name_, tdesc_type *type_, + int start_, int end_) + : name (name_), type (type_), start (start_), end (end_) + {} + + std::string name; + struct tdesc_type *type; + /* For non-enum-values, either both are -1 (non-bitfield), or both are + not -1 (bitfield). For enum values, start is the value (which could be + -1), end is -1. */ + int start, end; +}; + +/* tdesc_type for struct, union, flags, and enum types. */ + +struct tdesc_type_with_fields : tdesc_type +{ + tdesc_type_with_fields (const std::string &name, tdesc_type_kind kind, + int size_ = 0) + : tdesc_type (name, kind), size (size_) + {} + + void accept (tdesc_element_visitor &v) const override + { + v.visit (this); + } + + std::vector<tdesc_type_field> fields; + int size; +}; + +/* A feature from a target description. Each feature is a collection + of other elements, e.g. registers and types. */ + +struct tdesc_feature : tdesc_element +{ + tdesc_feature (const std::string &name_) + : name (name_) + {} + + virtual ~tdesc_feature () = default; + + DISABLE_COPY_AND_ASSIGN (tdesc_feature); + + /* The name of this feature. It may be recognized by the architecture + support code. */ + std::string name; + + /* The registers associated with this feature. */ + std::vector<tdesc_reg_up> registers; + + /* The types associated with this feature. */ + std::vector<tdesc_type_up> types; + + void accept (tdesc_element_visitor &v) const override; + + bool operator== (const tdesc_feature &other) const; + + bool operator!= (const tdesc_feature &other) const + { + return !(*this == other); + } +}; + +typedef std::unique_ptr<tdesc_feature> tdesc_feature_up; + +/* Allocate a new target_desc. */ +target_desc *allocate_target_description (void); + +/* Set TARGET_DESC's architecture by NAME. */ +void set_tdesc_architecture (target_desc *target_desc, + const char *name); + +/* Return the architecture associated with this target description as a string, + or NULL if no architecture was specified. */ +const char *tdesc_architecture_name (const struct target_desc *target_desc); + +/* Set TARGET_DESC's osabi by NAME. */ +void set_tdesc_osabi (target_desc *target_desc, const char *name); + +/* Return the osabi associated with this target description as a string, + or NULL if no osabi was specified. */ +const char *tdesc_osabi_name (const struct target_desc *target_desc); + +/* Return the type associated with ID in the context of FEATURE, or + NULL if none. */ +struct tdesc_type *tdesc_named_type (const struct tdesc_feature *feature, + const char *id); + +/* Return the created feature named NAME in target description TDESC. */ +struct tdesc_feature *tdesc_create_feature (struct target_desc *tdesc, + const char *name); + +/* Return the created vector tdesc_type named NAME in FEATURE. */ +struct tdesc_type *tdesc_create_vector (struct tdesc_feature *feature, + const char *name, + struct tdesc_type *field_type, + int count); + +/* Return the created struct tdesc_type named NAME in FEATURE. */ +tdesc_type_with_fields *tdesc_create_struct (struct tdesc_feature *feature, + const char *name); + +/* Return the created union tdesc_type named NAME in FEATURE. */ +tdesc_type_with_fields *tdesc_create_union (struct tdesc_feature *feature, + const char *name); + +/* Return the created flags tdesc_type named NAME in FEATURE. */ +tdesc_type_with_fields *tdesc_create_flags (struct tdesc_feature *feature, + const char *name, + int size); + +/* Return the created enum tdesc_type named NAME in FEATURE. */ +tdesc_type_with_fields *tdesc_create_enum (struct tdesc_feature *feature, + const char *name, + int size); + +/* Add a new field to TYPE. FIELD_NAME is its name, and FIELD_TYPE is + its type. */ +void tdesc_add_field (tdesc_type_with_fields *type, const char *field_name, + struct tdesc_type *field_type); + +/* Add a new bitfield to TYPE, with range START to END. FIELD_NAME is its name, + and FIELD_TYPE is its type. */ +void tdesc_add_typed_bitfield (tdesc_type_with_fields *type, + const char *field_name, + int start, int end, + struct tdesc_type *field_type); + +/* Set the total length of TYPE. Structs which contain bitfields may + omit the reserved bits, so the end of the last field may not + suffice. */ +void tdesc_set_struct_size (tdesc_type_with_fields *type, int size); + +/* Add a new untyped bitfield to TYPE. + Untyped bitfields become either uint32 or uint64 depending on the size + of the underlying type. */ +void tdesc_add_bitfield (tdesc_type_with_fields *type, const char *field_name, + int start, int end); + +/* A flag is just a typed(bool) single-bit bitfield. + This function is kept to minimize changes in generated files. */ +void tdesc_add_flag (tdesc_type_with_fields *type, int start, + const char *flag_name); + +/* Add field with VALUE and NAME to the enum TYPE. */ +void tdesc_add_enum_value (tdesc_type_with_fields *type, int value, + const char *name); + +/* Create a register in feature FEATURE. */ +void tdesc_create_reg (struct tdesc_feature *feature, const char *name, + int regnum, int save_restore, const char *group, + int bitsize, const char *type); + +/* Return the tdesc in string XML format. */ + +const char *tdesc_get_features_xml (const target_desc *tdesc); + +/* Print target description as xml. */ + +class print_xml_feature : public tdesc_element_visitor +{ +public: + print_xml_feature (std::string *buffer_) + : m_buffer (buffer_) + {} + + void visit_pre (const target_desc *e) override; + void visit_post (const target_desc *e) override; + void visit_pre (const tdesc_feature *e) override; + void visit_post (const tdesc_feature *e) override; + void visit (const tdesc_type_builtin *type) override; + void visit (const tdesc_type_vector *type) override; + void visit (const tdesc_type_with_fields *type) override; + void visit (const tdesc_reg *reg) override; + +private: + std::string *m_buffer; +}; + +#endif /* COMMON_TDESC_H */ diff --git a/gdbsupport/thread-pool.c b/gdbsupport/thread-pool.c new file mode 100644 index 0000000..fc83ff7 --- /dev/null +++ b/gdbsupport/thread-pool.c @@ -0,0 +1,167 @@ +/* Thread pool + + Copyright (C) 2019-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "common-defs.h" + +#if CXX_STD_THREAD + +#include "gdbsupport/thread-pool.h" +#include "gdbsupport/alt-stack.h" +#include "gdbsupport/block-signals.h" +#include <algorithm> + +/* On the off chance that we have the pthread library on a Windows + host, but std::thread is not using it, avoid calling + pthread_setname_np on Windows. */ +#ifndef _WIN32 +#ifdef HAVE_PTHREAD_SETNAME_NP +#define USE_PTHREAD_SETNAME_NP +#endif +#endif + +#ifdef USE_PTHREAD_SETNAME_NP + +#include <pthread.h> + +/* Handle platform discrepancies in pthread_setname_np: macOS uses a + single-argument form, while Linux uses a two-argument form. This + wrapper handles the difference. */ + +ATTRIBUTE_UNUSED static void +set_thread_name (int (*set_name) (pthread_t, const char *), const char *name) +{ + set_name (pthread_self (), name); +} + +/* The macOS man page says that pthread_setname_np returns "void", but + the headers actually declare it returning "int". */ +ATTRIBUTE_UNUSED static void +set_thread_name (int (*set_name) (const char *), const char *name) +{ + set_name (name); +} + +#endif /* USE_PTHREAD_SETNAME_NP */ + +namespace gdb +{ + +/* The thread pool detach()s its threads, so that the threads will not + prevent the process from exiting. However, it was discovered that + if any detached threads were still waiting on a condition variable, + then the condition variable's destructor would wait for the threads + to exit -- defeating the purpose. + + Allocating the thread pool on the heap and simply "leaking" it + avoids this problem. +*/ +thread_pool *thread_pool::g_thread_pool = new thread_pool (); + +thread_pool::~thread_pool () +{ + /* Because this is a singleton, we don't need to clean up. The + threads are detached so that they won't prevent process exit. + And, cleaning up here would be actively harmful in at least one + case -- see the comment by the definition of g_thread_pool. */ +} + +void +thread_pool::set_thread_count (size_t num_threads) +{ + std::lock_guard<std::mutex> guard (m_tasks_mutex); + + /* If the new size is larger, start some new threads. */ + if (m_thread_count < num_threads) + { + /* Ensure that signals used by gdb are blocked in the new + threads. */ + block_signals blocker; + for (size_t i = m_thread_count; i < num_threads; ++i) + { + std::thread thread (&thread_pool::thread_function, this); + thread.detach (); + } + } + /* If the new size is smaller, terminate some existing threads. */ + if (num_threads < m_thread_count) + { + for (size_t i = num_threads; i < m_thread_count; ++i) + m_tasks.emplace (); + m_tasks_cv.notify_all (); + } + + m_thread_count = num_threads; +} + +std::future<void> +thread_pool::post_task (std::function<void ()> func) +{ + std::packaged_task<void ()> t (func); + std::future<void> f = t.get_future (); + + if (m_thread_count == 0) + { + /* Just execute it now. */ + t (); + } + else + { + std::lock_guard<std::mutex> guard (m_tasks_mutex); + m_tasks.emplace (std::move (t)); + m_tasks_cv.notify_one (); + } + return f; +} + +void +thread_pool::thread_function () +{ +#ifdef USE_PTHREAD_SETNAME_NP + /* This must be done here, because on macOS one can only set the + name of the current thread. */ + set_thread_name (pthread_setname_np, "gdb worker"); +#endif + + /* Ensure that SIGSEGV is delivered to an alternate signal + stack. */ + gdb::alternate_signal_stack signal_stack; + + while (true) + { + optional<task> t; + + { + /* We want to hold the lock while examining the task list, but + not while invoking the task function. */ + std::unique_lock<std::mutex> guard (m_tasks_mutex); + while (m_tasks.empty ()) + m_tasks_cv.wait (guard); + t = std::move (m_tasks.front()); + m_tasks.pop (); + } + + if (!t.has_value ()) + break; + (*t) (); + } +} + +} + +#endif /* CXX_STD_THREAD */ diff --git a/gdbsupport/thread-pool.h b/gdbsupport/thread-pool.h new file mode 100644 index 0000000..2fb4453 --- /dev/null +++ b/gdbsupport/thread-pool.h @@ -0,0 +1,90 @@ +/* Thread pool + + Copyright (C) 2019-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef GDBSUPPORT_THREAD_POOL_H +#define GDBSUPPORT_THREAD_POOL_H + +#include <queue> +#include <thread> +#include <vector> +#include <functional> +#include <mutex> +#include <condition_variable> +#include <future> +#include "gdbsupport/gdb_optional.h" + +namespace gdb +{ + +/* A thread pool. + + There is a single global thread pool, see g_thread_pool. Tasks can + be submitted to the thread pool. They will be processed in worker + threads as time allows. */ +class thread_pool +{ +public: + /* The sole global thread pool. */ + static thread_pool *g_thread_pool; + + ~thread_pool (); + DISABLE_COPY_AND_ASSIGN (thread_pool); + + /* Set the thread count of this thread pool. By default, no threads + are created -- the thread count must be set first. */ + void set_thread_count (size_t num_threads); + + /* Return the number of executing threads. */ + size_t thread_count () const + { + return m_thread_count; + } + + /* Post a task to the thread pool. A future is returned, which can + be used to wait for the result. */ + std::future<void> post_task (std::function<void ()> func); + +private: + + thread_pool () = default; + + /* The callback for each worker thread. */ + void thread_function (); + + /* The current thread count. */ + size_t m_thread_count = 0; + + /* A convenience typedef for the type of a task. */ + typedef std::packaged_task<void ()> task; + + /* The tasks that have not been processed yet. An optional is used + to represent a task. If the optional is empty, then this means + that the receiving thread should terminate. If the optional is + non-empty, then it is an actual task to evaluate. */ + std::queue<optional<task>> m_tasks; + + /* A condition variable and mutex that are used for communication + between the main thread and the worker threads. */ + std::condition_variable m_tasks_cv; + std::mutex m_tasks_mutex; +}; + +} + +#endif /* GDBSUPPORT_THREAD_POOL_H */ diff --git a/gdbsupport/traits.h b/gdbsupport/traits.h new file mode 100644 index 0000000..2a6f006 --- /dev/null +++ b/gdbsupport/traits.h @@ -0,0 +1,109 @@ +/* Copyright (C) 2017-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_TRAITS_H +#define COMMON_TRAITS_H + +#include <type_traits> + +/* GCC does not understand __has_feature. */ +#if !defined(__has_feature) +# define __has_feature(x) 0 +#endif + +/* HAVE_IS_TRIVIALLY_COPYABLE is defined as 1 iff + std::is_trivially_copyable is available. GCC only implemented it + in GCC 5. */ +#if (__has_feature(is_trivially_copyable) \ + || (defined __GNUC__ && __GNUC__ >= 5)) +# define HAVE_IS_TRIVIALLY_COPYABLE 1 +#endif + +/* HAVE_IS_TRIVIALLY_CONSTRUCTIBLE is defined as 1 iff + std::is_trivially_constructible is available. GCC only implemented it + in GCC 5. */ +#if (__has_feature(is_trivially_constructible) \ + || (defined __GNUC__ && __GNUC__ >= 5)) +# define HAVE_IS_TRIVIALLY_CONSTRUCTIBLE 1 +#endif + +namespace gdb { + +/* Pre C++14-safe (CWG 1558) version of C++17's std::void_t. See + <http://en.cppreference.com/w/cpp/types/void_t>. */ + +template<typename... Ts> +struct make_void { typedef void type; }; + +template<typename... Ts> +using void_t = typename make_void<Ts...>::type; + +/* A few trait helpers, mainly stolen from libstdc++. Uppercase + because "and/or", etc. are reserved keywords. */ + +template<typename Predicate> +struct Not : public std::integral_constant<bool, !Predicate::value> +{}; + +template<typename...> +struct Or; + +template<> +struct Or<> : public std::false_type +{}; + +template<typename B1> +struct Or<B1> : public B1 +{}; + +template<typename B1, typename B2> +struct Or<B1, B2> + : public std::conditional<B1::value, B1, B2>::type +{}; + +template<typename B1,typename B2,typename B3, typename... Bn> +struct Or<B1, B2, B3, Bn...> + : public std::conditional<B1::value, B1, Or<B2, B3, Bn...>>::type +{}; + +template<typename...> +struct And; + +template<> +struct And<> : public std::true_type +{}; + +template<typename B1> +struct And<B1> : public B1 +{}; + +template<typename B1, typename B2> +struct And<B1, B2> + : public std::conditional<B1::value, B2, B1>::type +{}; + +template<typename B1, typename B2, typename B3, typename... Bn> +struct And<B1, B2, B3, Bn...> + : public std::conditional<B1::value, And<B2, B3, Bn...>, B1>::type +{}; + +/* Concepts-light-like helper to make SFINAE logic easier to read. */ +template<typename Condition> +using Requires = typename std::enable_if<Condition::value, void>::type; +} + +#endif /* COMMON_TRAITS_H */ diff --git a/gdbsupport/underlying.h b/gdbsupport/underlying.h new file mode 100644 index 0000000..a90aedb --- /dev/null +++ b/gdbsupport/underlying.h @@ -0,0 +1,32 @@ +/* Copyright (C) 2017-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_UNDERLYING_H +#define COMMON_UNDERLYING_H + +#include <type_traits> + +/* Convert an enum to its underlying value. */ + +template<typename E> +constexpr typename std::underlying_type<E>::type +to_underlying (E val) noexcept +{ + return static_cast<typename std::underlying_type<E>::type> (val); +} + +#endif diff --git a/gdbsupport/valid-expr.h b/gdbsupport/valid-expr.h new file mode 100644 index 0000000..b1c8446 --- /dev/null +++ b/gdbsupport/valid-expr.h @@ -0,0 +1,108 @@ +/* Compile-time valid expression checker for GDB, the GNU debugger. + + Copyright (C) 2017-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +/* Helper macros used to build compile-time unit tests that make sure + that invalid expressions that should not compile would not compile, + and that expressions that should compile do compile, and have the + right type. This is mainly used to verify that some utility's API + is really as safe as intended. */ + +#ifndef COMMON_VALID_EXPR_H +#define COMMON_VALID_EXPR_H + +#include "gdbsupport/preprocessor.h" +#include "gdbsupport/traits.h" + +/* Macro that uses SFINAE magic to detect whether the EXPR expression + is either valid or ill-formed, at compile time, without actually + producing compile-time errors. I.e., check that bad uses of the + types (e.g., involving mismatching types) would be caught at + compile time. If the expression is valid, also check whether the + expression has the right type. + + EXPR must be defined in terms of some of the template parameters, + so that template substitution failure discards the overload instead + of causing a real compile error. TYPES is thus the list of types + involved in the expression, and TYPENAMES is the same list, but + with each element prefixed by "typename". These are passed as + template parameter types to the templates within the macro. + + VALID is a boolean that indicates whether the expression is + supposed to be valid or invalid. + + EXPR_TYPE is the expected type of EXPR. Only meaningful iff VALID + is true. If VALID is false, then you must pass "void" as expected + type. + + Each invocation of the macro is wrapped in its own namespace to + avoid ODR violations. The generated namespace only includes the + line number, so client code should wrap sets of calls in a + test-specific namespace too, to fully guarantee uniqueness between + the multiple clients in the codebase. */ +#define CHECK_VALID_EXPR_INT(TYPENAMES, TYPES, VALID, EXPR_TYPE, EXPR) \ + namespace CONCAT (check_valid_expr, __LINE__) { \ + \ + template<typename, typename, typename = void> \ + struct is_valid_expression \ + : std::false_type {}; \ + \ + template <TYPENAMES> \ + struct is_valid_expression<TYPES, gdb::void_t<decltype (EXPR)>> \ + : std::true_type {}; \ + \ + static_assert (is_valid_expression<TYPES>::value == VALID, \ + ""); \ + \ + template<TYPENAMES, typename = void> \ + struct is_same_type \ + : std::is_same<EXPR_TYPE, void> {}; \ + \ + template <TYPENAMES> \ + struct is_same_type<TYPES, gdb::void_t<decltype (EXPR)>> \ + : std::is_same<EXPR_TYPE, decltype (EXPR)> {}; \ + \ + static_assert (is_same_type<TYPES>::value, ""); \ + } /* namespace */ + +/* A few convenience macros that support expressions involving a + varying numbers of types. If you need more types, feel free to add + another variant. */ + +#define CHECK_VALID_EXPR_1(T1, VALID, EXPR_TYPE, EXPR) \ + CHECK_VALID_EXPR_INT (ESC_PARENS (typename T1), \ + ESC_PARENS (T1), \ + VALID, EXPR_TYPE, EXPR) + +#define CHECK_VALID_EXPR_2(T1, T2, VALID, EXPR_TYPE, EXPR) \ + CHECK_VALID_EXPR_INT (ESC_PARENS(typename T1, typename T2), \ + ESC_PARENS (T1, T2), \ + VALID, EXPR_TYPE, EXPR) + +#define CHECK_VALID_EXPR_3(T1, T2, T3, VALID, EXPR_TYPE, EXPR) \ + CHECK_VALID_EXPR_INT (ESC_PARENS (typename T1, typename T2, typename T3), \ + ESC_PARENS (T1, T2, T3), \ + VALID, EXPR_TYPE, EXPR) + +#define CHECK_VALID_EXPR_4(T1, T2, T3, T4, VALID, EXPR_TYPE, EXPR) \ + CHECK_VALID_EXPR_INT (ESC_PARENS (typename T1, typename T2, \ + typename T3, typename T4), \ + ESC_PARENS (T1, T2, T3, T4), \ + VALID, EXPR_TYPE, EXPR) + +#endif /* COMMON_VALID_EXPR_H */ diff --git a/gdbsupport/version.h b/gdbsupport/version.h new file mode 100644 index 0000000..9c94fec --- /dev/null +++ b/gdbsupport/version.h @@ -0,0 +1,31 @@ +/* Version information for GDB. + Copyright (C) 1999-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_VERSION_H +#define COMMON_VERSION_H + +/* Version number of GDB, as a string. */ +extern const char version[]; + +/* Canonical host name as a string. */ +extern const char host_name[]; + +/* Canonical target name as a string. */ +extern const char target_name[]; + +#endif /* COMMON_VERSION_H */ diff --git a/gdbsupport/x86-xstate.h b/gdbsupport/x86-xstate.h new file mode 100644 index 0000000..0331d8f --- /dev/null +++ b/gdbsupport/x86-xstate.h @@ -0,0 +1,88 @@ +/* Common code for x86 XSAVE extended state. + + Copyright (C) 2010-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_X86_XSTATE_H +#define COMMON_X86_XSTATE_H + +/* The extended state feature bits. */ +#define X86_XSTATE_X87 (1ULL << 0) +#define X86_XSTATE_SSE (1ULL << 1) +#define X86_XSTATE_AVX (1ULL << 2) +#define X86_XSTATE_BNDREGS (1ULL << 3) +#define X86_XSTATE_BNDCFG (1ULL << 4) +#define X86_XSTATE_MPX (X86_XSTATE_BNDREGS | X86_XSTATE_BNDCFG) + +/* AVX 512 adds three feature bits. All three must be enabled. */ +#define X86_XSTATE_K (1ULL << 5) +#define X86_XSTATE_ZMM_H (1ULL << 6) +#define X86_XSTATE_ZMM (1ULL << 7) +#define X86_XSTATE_AVX512 (X86_XSTATE_K | X86_XSTATE_ZMM_H \ + | X86_XSTATE_ZMM) + +#define X86_XSTATE_PKRU (1ULL << 9) + +/* Supported mask and size of the extended state. */ +#define X86_XSTATE_X87_MASK X86_XSTATE_X87 +#define X86_XSTATE_SSE_MASK (X86_XSTATE_X87 | X86_XSTATE_SSE) +#define X86_XSTATE_AVX_MASK (X86_XSTATE_SSE_MASK | X86_XSTATE_AVX) +#define X86_XSTATE_MPX_MASK (X86_XSTATE_SSE_MASK | X86_XSTATE_MPX) +#define X86_XSTATE_AVX_MPX_MASK (X86_XSTATE_AVX_MASK | X86_XSTATE_MPX) +#define X86_XSTATE_AVX_AVX512_MASK (X86_XSTATE_AVX_MASK | X86_XSTATE_AVX512) +#define X86_XSTATE_AVX_MPX_AVX512_PKU_MASK (X86_XSTATE_AVX_MPX_MASK\ + | X86_XSTATE_AVX512 | X86_XSTATE_PKRU) + +#define X86_XSTATE_ALL_MASK (X86_XSTATE_AVX_MPX_AVX512_PKU_MASK) + + +#define X86_XSTATE_SSE_SIZE 576 +#define X86_XSTATE_AVX_SIZE 832 +#define X86_XSTATE_BNDREGS_SIZE 1024 +#define X86_XSTATE_BNDCFG_SIZE 1088 +#define X86_XSTATE_AVX512_SIZE 2688 +#define X86_XSTATE_PKRU_SIZE 2696 +#define X86_XSTATE_MAX_SIZE 2696 + + +/* In case one of the MPX XCR0 bits is set we consider we have MPX. */ +#define HAS_MPX(XCR0) (((XCR0) & X86_XSTATE_MPX) != 0) +#define HAS_AVX(XCR0) (((XCR0) & X86_XSTATE_AVX) != 0) +#define HAS_AVX512(XCR0) (((XCR0) & X86_XSTATE_AVX512) != 0) +#define HAS_PKRU(XCR0) (((XCR0) & X86_XSTATE_PKRU) != 0) + +/* Get I386 XSAVE extended state size. */ +#define X86_XSTATE_SIZE(XCR0) \ + (HAS_PKRU (XCR0) ? X86_XSTATE_PKRU_SIZE : \ + (HAS_AVX512 (XCR0) ? X86_XSTATE_AVX512_SIZE : \ + (HAS_MPX (XCR0) ? X86_XSTATE_BNDCFG_SIZE : \ + (HAS_AVX (XCR0) ? X86_XSTATE_AVX_SIZE : X86_XSTATE_SSE_SIZE)))) + +/* Initial value for fctrl register, as defined in the X86 manual, and + confirmed in the (Linux) kernel source. When the x87 floating point + feature is not enabled in an inferior we use this as the value of the + fcrtl register. */ + +#define I387_FCTRL_INIT_VAL 0x037f + +/* Initial value for mxcsr register. When the avx and sse floating point + features are not enabled in an inferior we use this as the value of the + mxcsr register. */ + +#define I387_MXCSR_INIT_VAL 0x1f80 + +#endif /* COMMON_X86_XSTATE_H */ diff --git a/gdbsupport/xml-utils.c b/gdbsupport/xml-utils.c new file mode 100644 index 0000000..3c6c11a --- /dev/null +++ b/gdbsupport/xml-utils.c @@ -0,0 +1,63 @@ +/* Shared helper routines for manipulating XML. + + Copyright (C) 2006-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "common-defs.h" +#include "xml-utils.h" + +/* See xml-utils.h. */ + +std::string +xml_escape_text (const char *text) +{ + std::string result; + + xml_escape_text_append (&result, text); + + return result; +} + +/* See xml-utils.h. */ + +void +xml_escape_text_append (std::string *result, const char *text) +{ + /* Expand the result. */ + for (int i = 0; text[i] != '\0'; i++) + switch (text[i]) + { + case '\'': + *result += "'"; + break; + case '\"': + *result += """; + break; + case '&': + *result += "&"; + break; + case '<': + *result += "<"; + break; + case '>': + *result += ">"; + break; + default: + *result += text[i]; + break; + } +} diff --git a/gdbsupport/xml-utils.h b/gdbsupport/xml-utils.h new file mode 100644 index 0000000..19dead4 --- /dev/null +++ b/gdbsupport/xml-utils.h @@ -0,0 +1,33 @@ +/* Shared helper routines for manipulating XML. + + Copyright (C) 2006-2020 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef COMMON_XML_UTILS_H +#define COMMON_XML_UTILS_H + +/* Return a string with special characters from TEXT replaced by entity + references. */ + +extern std::string xml_escape_text (const char *text); + +/* Append TEXT to RESULT, with special characters replaced by entity + references. */ + +extern void xml_escape_text_append (std::string *result, const char *text); + +#endif /* COMMON_XML_UTILS_H */ |