From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 15007 invoked by alias); 21 Nov 2014 15:34:25 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 14996 invoked by uid 89); 21 Nov 2014 15:34:24 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.9 required=5.0 tests=AWL,BAYES_00,FREEMAIL_FROM,RCVD_IN_DNSWL_LOW,SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-pd0-f172.google.com Received: from mail-pd0-f172.google.com (HELO mail-pd0-f172.google.com) (209.85.192.172) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Fri, 21 Nov 2014 15:34:17 +0000 Received: by mail-pd0-f172.google.com with SMTP id v10so5469268pde.17 for ; Fri, 21 Nov 2014 07:34:14 -0800 (PST) X-Received: by 10.66.155.2 with SMTP id vs2mr8011635pab.135.1416584053952; Fri, 21 Nov 2014 07:34:13 -0800 (PST) Received: from msticlxl57.ims.intel.com (fmdmzpr04-ext.fm.intel.com. [192.55.55.39]) by mx.google.com with ESMTPSA id qf1sm5152218pdb.49.2014.11.21.07.34.10 for (version=TLSv1 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 21 Nov 2014 07:34:13 -0800 (PST) Date: Fri, 21 Nov 2014 16:04:00 -0000 From: Ilya Enkovich To: Jeff Law Cc: Joseph Myers , Andi Kleen , gcc-patches Subject: Re: [PATCH, MPX runtime 1/2] Integrate MPX runtime library Message-ID: <20141121153405.GB30483@msticlxl57.ims.intel.com> References: <20141112160432.GA5697@msticlxl57.ims.intel.com> <20141119141555.GD47331@msticlxl57.ims.intel.com> <546CD981.1040002@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.21 (2010-09-15) X-IsSubscribed: yes X-SW-Source: 2014-11/txt/msg02813.txt.bz2 On 19 Nov 21:11, Ilya Enkovich wrote: > 2014-11-19 20:55 GMT+03:00 Jeff Law : > > On 11/19/14 07:15, Ilya Enkovich wrote: > > > >> -- > >> 2014-11-19 Ilya Enkovich > >> > >> * Makefile.def: Add libmpx. > >> * configure.ac: Add libmpx. > >> * Makefile.in: Regenerate. > >> * configure: Regenerate. > >> > >> gcc/ > >> > >> 2014-11-19 Ilya Enkovich > >> > >> * gcc.c (LIBMPX_LIBS): New. > >> (LIBMPX_SPEC): New. > >> (MPX_SPEC): New. > >> (LINK_COMMAND_SPEC): Add MPX_SPEC. > >> * c-family/c.opt (static-libmpx): New. > >> > >> libmpx/ > >> > >> 2014-11-19 Ilya Enkovich > >> > >> Initial commit. > > > > So I have only done a cursory peek at this code, but one thing which I did > > immediately note was the CPU feature testing stuff. Shouldn't all that > > stuff be integrated into the feature testing bits already found in libgcc? > > I'll have a look at these features. > > > > > I've asked the steering committee to vote on accepting the runtime -- > > necessary given Intel is keeping copyright ownership to the best of my > > knowledge. > > Thanks! > > Ilya > > > > > Jeff > > Jakub objected adding CPUID checks used in MPX runtime into __builtin_cpu_supports. So I just added required bits into cpuid.h and removed local implementation of cpuid. Is it OK? Thanks, Ilya -- 2014-11-21 Ilya Enkovich * Makefile.def: Add libmpx. * configure.ac: Add libmpx. * Makefile.in: Regenerate. * configure: Regenerate. gcc/ 2014-11-21 Ilya Enkovich * config/i386/cpuid.h (bit_MPX): New. (bit_BNDREGS): New. (bit_BNDCSR): New. * gcc.c (LIBMPX_LIBS): New. (LIBMPX_SPEC): New. (MPX_SPEC): New. (LINK_COMMAND_SPEC): Add MPX_SPEC. * c-family/c.opt (static-libmpx): New. libmpx/ 2014-11-21 Ilya Enkovich Initial commit. diff --git a/Makefile.def b/Makefile.def index 40bbca9..4a535d2 100644 --- a/Makefile.def +++ b/Makefile.def @@ -128,6 +128,9 @@ target_modules = { module= libsanitizer; bootstrap=true; lib_path=.libs; raw_cxx=true; }; +target_modules = { module= libmpx; + bootstrap=true; + lib_path=.libs; }; target_modules = { module= libvtv; bootstrap=true; lib_path=.libs; diff --git a/configure.ac b/configure.ac index b27fb1d..ccb119b 100644 --- a/configure.ac +++ b/configure.ac @@ -162,6 +162,7 @@ target_libraries="target-libgcc \ target-libstdc++-v3 \ target-libsanitizer \ target-libvtv \ + target-libmpx \ target-libssp \ target-libquadmath \ target-libgfortran \ @@ -642,6 +643,25 @@ if test -d ${srcdir}/libvtv; then fi fi + +# Disable libmpx on unsupported systems. +if test -d ${srcdir}/libmpx; then + if test x$enable_libmpx = x; then + AC_MSG_CHECKING([for libmpx support]) + if (srcdir=${srcdir}/libmpx; \ + . ${srcdir}/configure.tgt; \ + test "$LIBMPX_SUPPORTED" != "yes") + then + AC_MSG_RESULT([no]) + noconfigdirs="$noconfigdirs target-libmpx" + else + AC_MSG_RESULT([yes]) + fi + fi +fi + + + # Disable libquadmath for some systems. case "${target}" in avr-*-*) @@ -2652,6 +2672,11 @@ if echo " ${target_configdirs} " | grep " libvtv " > /dev/null 2>&1 && bootstrap_target_libs=${bootstrap_target_libs}target-libvtv, fi +# If we are building libmpx, bootstrap it. +if echo " ${target_configdirs} " | grep " libmpx " > /dev/null 2>&1; then + bootstrap_target_libs=${bootstrap_target_libs}target-libmpx, +fi + # Determine whether gdb needs tk/tcl or not. # Use 'maybe' since enable_gdbtk might be true even if tk isn't available # and in that case we want gdb to be built without tk. Ugh! diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt index 85dcb98..8f5d76c 100644 --- a/gcc/c-family/c.opt +++ b/gcc/c-family/c.opt @@ -1040,6 +1040,9 @@ fchkp-instrument-marked-only C ObjC C++ ObjC++ LTO Report Var(flag_chkp_instrument_marked_only) Init(0) Instrument only functions marked with bnd_instrument attribute. +static-libmpx +Driver + fcilkplus C ObjC C++ ObjC++ LTO Report Var(flag_cilkplus) Init(0) Enable Cilk Plus diff --git a/gcc/config/i386/cpuid.h b/gcc/config/i386/cpuid.h index 133e356..f85cebb 100644 --- a/gcc/config/i386/cpuid.h +++ b/gcc/config/i386/cpuid.h @@ -72,6 +72,7 @@ #define bit_AVX2 (1 << 5) #define bit_BMI2 (1 << 8) #define bit_RTM (1 << 11) +#define bit_MPX (1 << 14) #define bit_AVX512F (1 << 16) #define bit_AVX512DQ (1 << 17) #define bit_RDSEED (1 << 18) @@ -87,6 +88,10 @@ /* %ecx */ #define bit_PREFETCHWT1 (1 << 0) +/* XFEATURE_ENABLED_MASK register bits (%eax == 13, %ecx == 0) */ +#define bit_BNDREGS (1 << 3) +#define bit_BNDCSR (1 << 4) + /* Extended State Enumeration Sub-leaf (%eax == 13, %ecx == 1) */ #define bit_XSAVEOPT (1 << 0) #define bit_XSAVEC (1 << 1) diff --git a/gcc/gcc.c b/gcc/gcc.c index 653ca8d..75e5767 100644 --- a/gcc/gcc.c +++ b/gcc/gcc.c @@ -809,6 +809,30 @@ proper position among the other output files. */ %{fvtable-verify=preinit: -lvtv -u_vtable_map_vars_start -u_vtable_map_vars_end}}" #endif +#ifndef LIBMPX_LIBS +#define LIBMPX_LIBS "\ + %:include(libmpx.spec)%(link_libmpx)" +#endif + +#ifndef LIBMPX_SPEC +#if defined(HAVE_LD_STATIC_DYNAMIC) +#define LIBMPX_SPEC "\ +%{mmpx:%{fcheck-pointer-bounds:\ + %{static:--whole-archive -lmpx --no-whole-archive" LIBMPX_LIBS "}\ + %{!static:%{static-libmpx:" LD_STATIC_OPTION " --whole-archive}\ + -lmpx %{static-libmpx:--no-whole-archive " LD_DYNAMIC_OPTION \ + LIBMPX_LIBS "}}}}" +#else +#define LIBMPX_SPEC "\ +%{mmpx:%{fcheck-pointer-bounds:-lmpx" LIBMPX_LIBS "}}" +#endif +#endif + +#ifndef MPX_SPEC +#define MPX_SPEC "\ +%{!nostdlib:%{!nodefaultlibs:" LIBMPX_SPEC "}}" +#endif + /* -u* was put back because both BSD and SysV seem to support it. */ /* %{static:} simply prevents an error message if the target machine doesn't handle -static. */ @@ -829,6 +853,7 @@ proper position among the other output files. */ "%X %{o*} %{e*} %{N} %{n} %{r}\ %{s} %{t} %{u*} %{z} %{Z} %{!nostdlib:%{!nostartfiles:%S}} " VTABLE_VERIFICATION_SPEC " \ %{static:} %{L*} %(mfwrap) %(link_libgcc) " SANITIZER_EARLY_SPEC " %o\ + " MPX_SPEC " \ %{fopenmp|ftree-parallelize-loops=*:%:include(libgomp.spec)%(link_gomp)}\ %{fcilkplus:%:include(libcilkrts.spec)%(link_cilkrts)}\ %{fgnu-tm:%:include(libitm.spec)%(link_itm)}\ diff --git a/libmpx/ChangeLog b/libmpx/ChangeLog new file mode 100644 index 0000000..2e2ea92 --- /dev/null +++ b/libmpx/ChangeLog @@ -0,0 +1,3 @@ +2014-11-10 Ilya Enkovich + + Initial checkin. diff --git a/libmpx/Makefile.am b/libmpx/Makefile.am new file mode 100644 index 0000000..6cee4ac --- /dev/null +++ b/libmpx/Makefile.am @@ -0,0 +1,47 @@ +ACLOCAL_AMFLAGS = -I .. -I ../config + +if LIBMPX_SUPPORTED +SUBDIRS = mpxrt +nodist_toolexeclib_HEADERS = libmpx.spec +endif + +## May be used by toolexeclibdir. +gcc_version := $(shell cat $(top_srcdir)/../gcc/BASE-VER) + +# Work around what appears to be a GNU make bug handling MAKEFLAGS +# values defined in terms of make variables, as is the case for CC and +# friends when we are called from the top level Makefile. +AM_MAKEFLAGS = \ + "AR_FLAGS=$(AR_FLAGS)" \ + "CC_FOR_BUILD=$(CC_FOR_BUILD)" \ + "CFLAGS=$(CFLAGS)" \ + "CXXFLAGS=$(CXXFLAGS)" \ + "CFLAGS_FOR_BUILD=$(CFLAGS_FOR_BUILD)" \ + "CFLAGS_FOR_TARGET=$(CFLAGS_FOR_TARGET)" \ + "INSTALL=$(INSTALL)" \ + "INSTALL_DATA=$(INSTALL_DATA)" \ + "INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \ + "INSTALL_SCRIPT=$(INSTALL_SCRIPT)" \ + "JC1FLAGS=$(JC1FLAGS)" \ + "LDFLAGS=$(LDFLAGS)" \ + "LIBCFLAGS=$(LIBCFLAGS)" \ + "LIBCFLAGS_FOR_TARGET=$(LIBCFLAGS_FOR_TARGET)" \ + "MAKE=$(MAKE)" \ + "MAKEINFO=$(MAKEINFO) $(MAKEINFOFLAGS)" \ + "PICFLAG=$(PICFLAG)" \ + "PICFLAG_FOR_TARGET=$(PICFLAG_FOR_TARGET)" \ + "SHELL=$(SHELL)" \ + "RUNTESTFLAGS=$(RUNTESTFLAGS)" \ + "exec_prefix=$(exec_prefix)" \ + "infodir=$(infodir)" \ + "libdir=$(libdir)" \ + "prefix=$(prefix)" \ + "includedir=$(includedir)" \ + "AR=$(AR)" \ + "AS=$(AS)" \ + "LD=$(LD)" \ + "LIBCFLAGS=$(LIBCFLAGS)" \ + "NM=$(NM)" \ + "PICFLAG=$(PICFLAG)" \ + "RANLIB=$(RANLIB)" \ + "DESTDIR=$(DESTDIR)" diff --git a/libmpx/acinclude.m4 b/libmpx/acinclude.m4 new file mode 100644 index 0000000..38e0808 --- /dev/null +++ b/libmpx/acinclude.m4 @@ -0,0 +1,12 @@ +dnl ---------------------------------------------------------------------- +dnl This whole bit snagged from libgfortran. + +sinclude(../libtool.m4) +dnl The lines below arrange for aclocal not to bring an installed +dnl libtool.m4 into aclocal.m4, while still arranging for automake to +dnl add a definition of LIBTOOL to Makefile.in. +ifelse(,,,[AC_SUBST(LIBTOOL) +AC_DEFUN([AM_PROG_LIBTOOL]) +AC_DEFUN([AC_LIBTOOL_DLOPEN]) +AC_DEFUN([AC_PROG_LD]) +]) diff --git a/libmpx/aclocal.m4 b/libmpx/aclocal.m4 new file mode 100644 index 0000000..029586b --- /dev/null +++ b/libmpx/aclocal.m4 @@ -0,0 +1,701 @@ +# generated automatically by aclocal 1.11.1 -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006, 2007, 2008, 2009 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_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.64],, +[m4_warning([this file was generated for autoconf 2.64. +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, 2003, 2005, 2006, 2007, 2008 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.11' +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.11.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.11.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, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# 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], +[dnl Rely on autoconf to set up CDPATH properly. +AC_PREREQ([2.50])dnl +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008 +# 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. + +# serial 9 + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ(2.52)dnl + ifelse([$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])]) + +# Do all the work for Automake. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006, 2008, 2009 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. + +# serial 16 + +# 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. + +# 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.62])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], +[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], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, + [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([AM_PROG_MKDIR_P])dnl +# We need awk for the "check" target. 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)], + [define([AC_PROG_CC], + defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES(CXX)], + [define([AC_PROG_CXX], + defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJC], + [_AM_DEPENDENCIES(OBJC)], + [define([AC_PROG_OBJC], + defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl +]) +_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl +dnl The `parallel-tests' driver may need to know about EXEEXT, so add the +dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro +dnl 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 +]) + +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, 2003, 2005, 2008 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}" != 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, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2008 +# 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. + +# serial 5 + +# 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 am_maintainer_other maintainer-specific portions of Makefiles]) + dnl maintainer-mode's default is 'disable' unless 'enable' is passed + AC_ARG_ENABLE([maintainer-mode], +[ --][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 +] +) + +AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE]) + +# Copyright (C) 1999, 2000, 2001, 2003, 2004, 2005, 2008 +# 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. + +# serial 6 + +# AM_PROG_CC_C_O +# -------------- +# Like AC_PROG_CC_C_O, but changed for automake. +AC_DEFUN([AM_PROG_CC_C_O], +[AC_REQUIRE([AC_PROG_CC_C_O])dnl +AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([compile])dnl +# FIXME: we rely on the cache variable name because +# there is no other way. +set dummy $CC +am_cc=`echo $[2] | sed ['s/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/']` +eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o +if test "$am_t" != 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 +dnl Make sure AC_PROG_CC is never called again, or it will override our +dnl setting of CC. +m4_define([AC_PROG_CC], + [m4_fatal([AC_PROG_CC cannot be called after AM_PROG_CC_C_O])]) +]) + +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008 +# 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. + +# serial 6 + +# 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 supports --run. +# If it does, 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 --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + AC_MSG_WARN([`missing' script is too old or missing]) +fi +]) + +# Copyright (C) 2003, 2004, 2005, 2006 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_MKDIR_P +# --------------- +# Check for `mkdir -p'. +AC_DEFUN([AM_PROG_MKDIR_P], +[AC_PREREQ([2.60])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, +dnl while keeping a definition of mkdir_p for backward compatibility. +dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. +dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of +dnl Makefile.ins that do not define MKDIR_P, so we do our own +dnl adjustment using top_builddir (which is defined more often than +dnl MKDIR_P). +AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl +case $mkdir_p in + [[\\/$]]* | ?:[[\\/]]*) ;; + */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; +esac +]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005, 2008 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. + +# serial 4 + +# _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])]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008 +# 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. + +# serial 5 + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftest.file +# 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 ( + 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 + rm -f conftest.file + 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 + + 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)]) + +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# 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, 2008 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. + +# serial 2 + +# _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, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# _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. +AM_MISSING_PROG([AMTAR], [tar]) +m4_if([$1], [v7], + [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], + [m4_case([$1], [ustar],, [pax],, + [m4_fatal([Unknown tar format])]) +AC_MSG_CHECKING([how to create a $1 tar archive]) +# Loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' +_am_tools=${am_cv_prog_tar_$1-$_am_tools} +# Do not fold the above two line into one, because Tru64 sh and +# Solaris sh will not grok spaces in the rhs of `-'. +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 /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/acx.m4]) +m4_include([../config/lead-dot.m4]) +m4_include([../config/libstdc++-raw-cxx.m4]) +m4_include([../config/multi.m4]) +m4_include([../config/override.m4]) +m4_include([../libtool.m4]) +m4_include([../ltoptions.m4]) +m4_include([../ltsugar.m4]) +m4_include([../ltversion.m4]) +m4_include([../lt~obsolete.m4]) diff --git a/libmpx/config.h.in b/libmpx/config.h.in new file mode 100644 index 0000000..a318e02 --- /dev/null +++ b/libmpx/config.h.in @@ -0,0 +1,100 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if you have the header file. */ +#undef HAVE_DLFCN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the `secure_getenv' function. */ +#undef HAVE_SECURE_GETENV + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#undef LT_OBJDIR + +/* Define to 1 if your C compiler doesn't accept -c and -o together. */ +#undef NO_MINUS_C_MINUS_O + +/* 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 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* 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 + + +/* Version number of package */ +#undef VERSION + +/* 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 diff --git a/libmpx/configure.ac b/libmpx/configure.ac new file mode 100644 index 0000000..bd7a5eb --- /dev/null +++ b/libmpx/configure.ac @@ -0,0 +1,126 @@ +# -*- Autoconf -*- +# Process this file with autoconf to produce a configure script. + +AC_PREREQ([2.64]) +AC_INIT(package-unused, version-unused, libmpx) + +# ------- +# Options +# ------- +AC_MSG_CHECKING([for --enable-version-specific-runtime-libs]) +AC_ARG_ENABLE(version-specific-runtime-libs, +[ --enable-version-specific-runtime-libs Specify that runtime libraries should be installed in a compiler-specific directory ], +[case "$enableval" in + yes) version_specific_libs=yes ;; + no) version_specific_libs=no ;; + *) AC_MSG_ERROR([Unknown argument to enable/disable version-specific libs]);; + esac], +[version_specific_libs=no]) +AC_MSG_RESULT($version_specific_libs) + +# Do not delete or change the following two lines. For why, see +# http://gcc.gnu.org/ml/libstdc++/2003-07/msg00451.html +AC_CANONICAL_SYSTEM +target_alias=${target_alias-$host_alias} +AC_SUBST(target_alias) +GCC_LIBSTDCXX_RAW_CXX_FLAGS + +# See if supported. +unset LIBMPX_SUPPORTED +AC_MSG_CHECKING([for target support for Intel MPX runtime library]) +. ${srcdir}/configure.tgt +AC_MSG_RESULT($LIBMPX_SUPPORTED) +AM_CONDITIONAL(LIBMPX_SUPPORTED, [test "x$LIBMPX_SUPPORTED" = "xyes"]) + +link_libmpx="-lpthread" +AC_SUBST(link_libmpx) + +AM_INIT_AUTOMAKE(foreign no-dist no-dependencies) +AM_ENABLE_MULTILIB(, ..) +AM_MAINTAINER_MODE + +AC_GNU_SOURCE +AC_CHECK_FUNCS([secure_getenv]) + +# Calculate toolexeclibdir +# Also toolexecdir, though it's only used in toolexeclibdir +case ${version_specific_libs} in + yes) + # Need the gcc compiler version to know where to install libraries + # and header files if --enable-version-specific-runtime-libs option + # is selected. + toolexecdir='$(libdir)/gcc/$(target_alias)' + toolexeclibdir='$(toolexecdir)/$(gcc_version)$(MULTISUBDIR)' + ;; + no) + if test -n "$with_cross_host" && + test x"$with_cross_host" != x"no"; then + # Install a library built with a cross compiler in tooldir, not libdir. + toolexecdir='$(exec_prefix)/$(target_alias)' + toolexeclibdir='$(toolexecdir)/lib' + else + toolexecdir='$(libdir)/gcc-lib/$(target_alias)' + toolexeclibdir='$(libdir)' + fi + multi_os_directory=`$CC -print-multi-os-directory` + case $multi_os_directory in + .) ;; # Avoid trailing /. + *) toolexeclibdir=$toolexeclibdir/$multi_os_directory ;; + esac + ;; +esac +AC_SUBST(toolexecdir) +AC_SUBST(toolexeclibdir) + +# Check for programs. +m4_rename([_AC_ARG_VAR_PRECIOUS],[real_PRECIOUS]) +m4_define([_AC_ARG_VAR_PRECIOUS],[]) +AC_PROG_CC +AC_PROG_CXX +m4_rename_force([real_PRECIOUS],[_AC_ARG_VAR_PRECIOUS]) + +AM_PROG_CC_C_O + +AC_SUBST(CFLAGS) + +# Newer automakes demand CCAS and CCASFLAGS. +: ${CCAS='$(CC)'} +: ${CCASFLAGS='$(CFLAGS)'} +AC_SUBST(CCAS) +AC_SUBST(CCASFLAGS) + +AC_CHECK_TOOL(AS, as) +AC_CHECK_TOOL(AR, ar) +AC_CHECK_TOOL(RANLIB, ranlib, :) + +# Configure libtool +AC_LIBTOOL_DLOPEN +AM_PROG_LIBTOOL +AC_SUBST(enable_shared) +AC_SUBST(enable_static) + +XCFLAGS="-Wall -Wextra" +AC_SUBST(XCFLAGS) + +if test "${multilib}" = "yes"; then + multilib_arg="--enable-multilib" +else + multilib_arg= +fi + +AC_CONFIG_FILES([Makefile libmpx.spec]) +AC_CONFIG_HEADERS(config.h) +AC_CONFIG_FILES(AC_FOREACH([DIR], [mpxrt], [DIR/Makefile]), + [cat > vpsed$$ << \_EOF +s!`test -f '$<' || echo '$(srcdir)/'`!! +_EOF + sed -f vpsed$$ $ac_file > tmp$$ + mv tmp$$ $ac_file + rm vpsed$$ + echo 'MULTISUBDIR =' >> $ac_file + ml_norecursion=yes + . ${multi_basedir}/config-ml.in + AS_UNSET([ml_norecursion]) +]) + +AC_OUTPUT diff --git a/libmpx/configure.tgt b/libmpx/configure.tgt new file mode 100644 index 0000000..103d8bd --- /dev/null +++ b/libmpx/configure.tgt @@ -0,0 +1,35 @@ +# -*- shell-script -*- +# Copyright (C) 2014 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU 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 . + +# This is the target specific configuration file. This is invoked by the +# autoconf generated configure script. Putting it in a separate shell file +# lets us skip running autoconf when modifying target specific information. + +# Filter out unsupported systems. +LIBMPX_SUPPORTED=no +case "${target}" in + x86_64-*-linux* | i?86-*-linux*) + # X32 doesn't support MPX. + echo "int i[sizeof (void *) == 4 ? 1 : -1] = { __x86_64__ };" > conftestx.c + if ${CC} ${CFLAGS} -c -o conftestx.o conftestx.c > /dev/null 2>&1; then + LIBMPX_SUPPORTED=no + else + LIBMPX_SUPPORTED=yes + fi + ;; + *) + ;; +esac diff --git a/libmpx/libmpx.spec.in b/libmpx/libmpx.spec.in new file mode 100644 index 0000000..a265e28 --- /dev/null +++ b/libmpx/libmpx.spec.in @@ -0,0 +1,3 @@ +# This spec file is read by gcc when linking. It is used to specify the +# standard libraries we need in order to link with libcilkrts. +*link_libmpx: @link_libmpx@ diff --git a/libmpx/libtool-version b/libmpx/libtool-version new file mode 100644 index 0000000..d1f57a0 --- /dev/null +++ b/libmpx/libtool-version @@ -0,0 +1,6 @@ +# This file is used to maintain libtool version info for libmpx. See +# the libtool manual to understand the meaning of the fields. This is +# a separate file so that version updates don't involve re-running +# automake. +# CURRENT:REVISION:AGE +0:0:0 diff --git a/libmpx/mpxrt/Makefile.am b/libmpx/mpxrt/Makefile.am new file mode 100644 index 0000000..5f5c21e --- /dev/null +++ b/libmpx/mpxrt/Makefile.am @@ -0,0 +1,59 @@ +ACLOCAL_AMFLAGS = -I $(top_srcdir) -I $(top_srcdir)/config + +if LIBMPX_SUPPORTED +# May be used by toolexeclibdir. +gcc_version := $(shell cat $(top_srcdir)/../gcc/BASE-VER) + +AM_CPPFLAGS = -I$(top_srcdir)/.. +AM_CFLAGS = $(XCFLAGS) + +toolexeclib_LTLIBRARIES = libmpx.la + +libmpx_la_SOURCES = mpxrt.c mpxrt-utils.c + +libmpx_la_DEPENDENCIES = libmpx.map +libmpx_la_LDFLAGS = -Wl,--version-script=$(srcdir)/libmpx.map $(link_libmpx) + +mpxrt.lo: mpxrt-utils.h +mpxrt-utils.lo: mpxrt-utils.h +endif + +# Work around what appears to be a GNU make bug handling MAKEFLAGS +# values defined in terms of make variables, as is the case for CC and +# friends when we are called from the top level Makefile. +AM_MAKEFLAGS = \ + "AR_FLAGS=$(AR_FLAGS)" \ + "CC_FOR_BUILD=$(CC_FOR_BUILD)" \ + "CFLAGS=$(CFLAGS)" \ + "CXXFLAGS=$(CXXFLAGS)" \ + "CFLAGS_FOR_BUILD=$(CFLAGS_FOR_BUILD)" \ + "CFLAGS_FOR_TARGET=$(CFLAGS_FOR_TARGET)" \ + "INSTALL=$(INSTALL)" \ + "INSTALL_DATA=$(INSTALL_DATA)" \ + "INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \ + "INSTALL_SCRIPT=$(INSTALL_SCRIPT)" \ + "JC1FLAGS=$(JC1FLAGS)" \ + "LDFLAGS=$(LDFLAGS)" \ + "LIBCFLAGS=$(LIBCFLAGS)" \ + "LIBCFLAGS_FOR_TARGET=$(LIBCFLAGS_FOR_TARGET)" \ + "MAKE=$(MAKE)" \ + "MAKEINFO=$(MAKEINFO) $(MAKEINFOFLAGS)" \ + "PICFLAG=$(PICFLAG)" \ + "PICFLAG_FOR_TARGET=$(PICFLAG_FOR_TARGET)" \ + "SHELL=$(SHELL)" \ + "RUNTESTFLAGS=$(RUNTESTFLAGS)" \ + "exec_prefix=$(exec_prefix)" \ + "infodir=$(infodir)" \ + "libdir=$(libdir)" \ + "prefix=$(prefix)" \ + "includedir=$(includedir)" \ + "AR=$(AR)" \ + "AS=$(AS)" \ + "LD=$(LD)" \ + "LIBCFLAGS=$(LIBCFLAGS)" \ + "NM=$(NM)" \ + "PICFLAG=$(PICFLAG)" \ + "RANLIB=$(RANLIB)" \ + "DESTDIR=$(DESTDIR)" + +MAKEOVERRIDES= diff --git a/libmpx/mpxrt/libmpx.map b/libmpx/mpxrt/libmpx.map new file mode 100644 index 0000000..90093b7 --- /dev/null +++ b/libmpx/mpxrt/libmpx.map @@ -0,0 +1,5 @@ +LIBMPX_1.0 +{ + local: + *; +}; diff --git a/libmpx/mpxrt/libtool-version b/libmpx/mpxrt/libtool-version new file mode 100644 index 0000000..5aa6ed7 --- /dev/null +++ b/libmpx/mpxrt/libtool-version @@ -0,0 +1,6 @@ +# This file is used to maintain libtool version info for libmpx. See +# the libtool manual to understand the meaning of the fields. This is +# a separate file so that version updates don't involve re-running +# automake. +# CURRENT:REVISION:AGE +1:0:0 diff --git a/libmpx/mpxrt/mpxrt-utils.c b/libmpx/mpxrt/mpxrt-utils.c new file mode 100644 index 0000000..db672c4 --- /dev/null +++ b/libmpx/mpxrt/mpxrt-utils.c @@ -0,0 +1,533 @@ +/* mpxrt-utils.c -*-C++-*- + * + ************************************************************************* + * + * @copyright + * Copyright (C) 2014, Intel Corporation + * All rights reserved. + * + * @copyright + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * @copyright + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY + * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************/ + +#define __STDC_FORMAT_MACROS +#include "config.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include "mpxrt-utils.h" + +#ifndef HAVE_SECURE_GETENV +#define secure_getenv __secure_getenv +#endif + +#define MPX_RT_OUT "CHKP_RT_OUT_FILE" +#define MPX_RT_ERR "CHKP_RT_ERR_FILE" +#define MPX_RT_VERBOSE "CHKP_RT_VERBOSE" +#define MPX_RT_VERBOSE_DEFAULT VERB_BR +#define MPX_RT_ENABLE "CHKP_RT_ENABLE" +#define MPX_RT_ENABLE_DEFAULT 1 +#define MPX_RT_MODE "CHKP_RT_MODE" +#define MPX_RT_MODE_DEFAULT MPX_RT_COUNT +#define MPX_RT_MODE_DEFAULT_STR "count" +#define MPX_RT_HELP "CHKP_RT_HELP" +#define MPX_RT_ADDPID "CHKP_RT_ADDPID" +#define MPX_RT_BNDPRESERVE "CHKP_RT_BNDPRESERVE" +#define MPX_RT_BNDPRESERVE_DEFAULT 0 +#define MPX_RT_PRINT_SUMMARY "CHKP_RT_PRINT_SUMMARY" + +#define MAX_FILE_NAME PATH_MAX + +typedef struct env_var_s { + char *env_name; + char *env_val; + struct env_var_s *next; +} env_var_t; + +typedef struct { + env_var_t *first; + env_var_t *last; +} env_var_list_t; + +/* Following vars are initialized at process startup only + and thus are considered to be thread safe. */ +static int summary; +static int add_pid; +static mpx_rt_mode_t mode; +static env_var_list_t env_var_list; +static verbose_type verbose_val; +static FILE *out; +static FILE *err; +static char out_name[MAX_FILE_NAME]; +static char err_name[MAX_FILE_NAME]; + +/* Following vars are read at process finalization only. + All write accesses use the same value and thus are + considered to be thread safe. */ +static int out_file_dirty; +static int err_file_dirty; +static int files_overwritten; + +/* Mutex used to sync output. */ +static pthread_mutex_t lock; + +static void * +malloc_check (size_t size) +{ + void *res = malloc (size); + if (!res) + __mpxrt_print (VERB_ERROR, "Couldn't allocate %zu bytes.", size); + else + memset (res, 0, size); + return res; +} + +static void +env_var_list_add (const char* env, const char* val) +{ + env_var_t* n; + + if (val == 0) + return; + + n = (env_var_t *)malloc_check (sizeof (env_var_t)); + if (!n) + return; + + if (env_var_list.first == 0) + env_var_list.first = n; + + if (env_var_list.last) + env_var_list.last->next = n; + + env_var_list.last = n; + + n->env_name = (char *)malloc_check (strlen (env) + 1); + n->env_val = (char *)malloc_check (strlen (val) + 1); + + if (!n->env_name || !n->env_val) + return; + + strcpy (n->env_name, env); + strcpy (n->env_val, val); +} + +static void +set_file_stream (FILE** file, char* file_name, + const char* env, FILE* deflt) +{ + int pid; + if (env != 0) + { + if (add_pid) + { + pid = getpid (); + snprintf (file_name, MAX_FILE_NAME, "%s.%d", env, pid); + } + else + snprintf (file_name, MAX_FILE_NAME, "%s", env); + + *file = fopen (file_name, "we"); + if (*file != 0) + return; + } + *file = deflt; +} + +/* + * this function will be called after fork in the child + * open new files with pid of the process + */ +static void +open_child_files () +{ + char *out_env; + char *err_env; + + out_env = secure_getenv (MPX_RT_OUT); + err_env = secure_getenv (MPX_RT_ERR); + + if (add_pid == 0 && (out_env != 0 || err_env != 0)) + { + __mpxrt_print (VERB_ERROR, "MPX RUNTIME WARNING: out/err files are " + "overwritten in new processes since %s was not set.\n", + MPX_RT_ADDPID); + files_overwritten = 1; + } + + set_file_stream (&out, out_name, out_env, stdout); + if (out_env == 0 || err_env == 0 || (strcmp (out_env, err_env) != 0)) + set_file_stream (&err, err_name, err_env, stderr); + else + /* in case we get the same file name for err and out */ + err = out; +} + +/* + * this function is called after fork in the parent + */ +static void +at_fork_check (void) +{ + char *out_env; + char *err_env; + + out_env = secure_getenv (MPX_RT_OUT); + err_env = secure_getenv (MPX_RT_ERR); + + if (add_pid == 0 && (out_env != 0 || err_env != 0)) + files_overwritten = 1; +} + +static mpx_rt_mode_t +set_mpx_rt_mode (const char *env) +{ + if (env == 0) + return MPX_RT_MODE_DEFAULT; + else if (strcmp (env, "stop") == 0) + return MPX_RT_STOP; + else if (strcmp (env,"count") == 0) + return MPX_RT_COUNT; + { + __mpxrt_print (VERB_ERROR, "Illegal value '%s' for %s. Legal values are" + "[stop | count]\nUsing default value %s\n", + env, MPX_RT_MODE, MPX_RT_MODE_DEFAULT_STR); + return MPX_RT_MODE_DEFAULT; + } +} + +static void +print_help (void) +{ + fprintf (out, "MPX Runtime environment variables help.\n"); + + fprintf (out, "%s \t set output file for info & debug [default: stdout]\n", + MPX_RT_OUT); + fprintf (out, "%s \t set output file for error [default: stderr]\n", + MPX_RT_ERR); + fprintf (out, "%s \t set verbosity type [default: %d]\n" + "\t\t\t 0 - print only internal run time errors\n" + "\t\t\t 1 - just print summary\n" + "\t\t\t 2 - print summary and bound violation information\n " + "\t\t\t 3 - print debug information\n", + MPX_RT_VERBOSE, MPX_RT_VERBOSE_DEFAULT); + fprintf (out, "%s \t\t set MPX runtime behavior on #BR exception." + " [stop | count]\n" + "\t\t\t [default: %s]\n", MPX_RT_MODE, MPX_RT_MODE_DEFAULT_STR); + fprintf (out, "%s \t\t generate out,err file for each process.\n" + "\t\t\t generated file will be MPX_RT_{OUT,ERR}_FILE.pid\n" + "\t\t\t [default: no]\n", MPX_RT_ADDPID); + fprintf (out, "%s \t set value for BNDPRESERVE bit.\n" + "\t\t\t BNDPRESERVE = 0 flush bounds on unprefixed call/ret/jmp\n" + "\t\t\t BNDPRESERVE = 1 do NOT flush bounds\n" + "\t\t\t [default: %d]\n", MPX_RT_BNDPRESERVE, + MPX_RT_BNDPRESERVE_DEFAULT); + fprintf (out, "%s \t set value for ENABLE bit.\n" + "\t\t\t ENABLE = 0 enable MPX feature\n" + "\t\t\t ENABLE = 1 disable MPX feature\n" + "\t\t\t [default: %d]\n", MPX_RT_ENABLE, + MPX_RT_ENABLE_DEFAULT); + fprintf (out, "%s \t print summary at the end of the run\n" + "\t\t\t [default: no]\n", MPX_RT_PRINT_SUMMARY); + + fprintf (out, "%s \t\t print this help and exit.\n" + "\t\t\t [default: no]\n", MPX_RT_HELP); + + exit (0); +} + +static void +validate_bndpreserve (const char *env, int *bndpreserve) +{ + if (env == 0) + bndpreserve = MPX_RT_BNDPRESERVE_DEFAULT; + else if (strcmp (env, "0") == 0) + *bndpreserve = 0; + else if (strcmp (env, "1") == 0) + *bndpreserve = 1; + else + { + __mpxrt_print (VERB_ERROR, "Illegal value '%s' for %s. Legal values " + "are [0 | 1]\nUsing default value %d\n", + env, MPX_RT_BNDPRESERVE, MPX_RT_BNDPRESERVE_DEFAULT); + *bndpreserve = MPX_RT_BNDPRESERVE_DEFAULT; + } +} + +static void +validate_enable (const char *env, int *enable) +{ + if (env == 0) + *enable = MPX_RT_ENABLE_DEFAULT; + else if (strcmp (env, "0") == 0) + *enable = 0; + else if (strcmp (env, "1") == 0) + *enable = 1; + else + { + __mpxrt_print (VERB_ERROR, "Illegal value '%s' for %s. Legal values " + "are [0 | 1]\nUsing default value %d\n", + env, MPX_RT_ENABLE, MPX_RT_ENABLE_DEFAULT); + *enable = MPX_RT_ENABLE_DEFAULT; + } +} + +static verbose_type +init_verbose_val (const char *env) +{ + if (env == 0) + return MPX_RT_VERBOSE_DEFAULT; + else if (strcmp(env, "0") == 0) + return VERB_ERROR; + else if (strcmp(env, "1") == 0) + return VERB_INFO; + else if (strcmp(env, "2") == 0) + return VERB_BR; + else if (strcmp(env, "3") == 0) + return VERB_DEBUG; + + __mpxrt_print (VERB_ERROR, "Illegal value '%s' for %s. Legal values " + "are [0..3]\nUsing default value %d\n", + env, MPX_RT_VERBOSE, (int)MPX_RT_VERBOSE_DEFAULT); + + return MPX_RT_VERBOSE_DEFAULT; +} + +static void +env_var_print_summary (void) +{ + env_var_t* node; + + __mpxrt_print (VERB_DEBUG, "Used environment variables:\n"); + + node = env_var_list.first; + while (node != 0) + { + __mpxrt_print (VERB_DEBUG, " %s = %s\n", node->env_name, node->env_val); + node = node->next; + } +} + +/* Return 1 if passes env var value should enable feature. */ + +static int +check_yes (const char *val) +{ + return val && (!strcmp (val, "yes") || !strcmp (val, "1")); +} + +void +__mpxrt_init_env_vars (int* bndpreserve, int *enable) +{ + char *out_env; + char *err_env; + char *env; + + pthread_mutex_init (&lock, NULL); + + out_env = secure_getenv (MPX_RT_OUT); + env_var_list_add (MPX_RT_OUT, out_env); + + err_env = secure_getenv (MPX_RT_ERR); + env_var_list_add (MPX_RT_ERR, err_env); + + env = secure_getenv (MPX_RT_ADDPID); + env_var_list_add (MPX_RT_ADDPID, env); + add_pid = check_yes (env); + + set_file_stream (&out, out_name, out_env, stdout); + if (out_env == 0 || err_env == 0 || (strcmp (out_env, err_env) != 0)) + set_file_stream (&err, err_name, err_env, stderr); + else + /* in case we get the same file name for err and out */ + err = out; + + env = secure_getenv (MPX_RT_VERBOSE); + env_var_list_add (MPX_RT_VERBOSE, env); + verbose_val = init_verbose_val (env); + + env = secure_getenv (MPX_RT_MODE); + env_var_list_add (MPX_RT_MODE, env); + mode = set_mpx_rt_mode (env); + + env = secure_getenv (MPX_RT_BNDPRESERVE); + env_var_list_add (MPX_RT_BNDPRESERVE, env); + validate_bndpreserve (env, bndpreserve); + + env = secure_getenv (MPX_RT_ENABLE); + env_var_list_add (MPX_RT_ENABLE, env); + validate_enable (env, enable); + + env = secure_getenv (MPX_RT_PRINT_SUMMARY); + env_var_list_add (MPX_RT_PRINT_SUMMARY, env); + summary = check_yes (env); + + env = secure_getenv (MPX_RT_HELP); + if (check_yes (env)) + print_help (); + + /* + * at fork - create new files for output and err according + * to the env vars. + */ + pthread_atfork (NULL, at_fork_check, open_child_files); + + env_var_print_summary (); +} + +void +__mpxrt_utils_free (void) +{ + if (files_overwritten) + __mpxrt_print (VERB_INFO, "\nMPX RUNTIME WARNING: out/err files are" + " overwritten in new processes since %s was not set.\n", + MPX_RT_ADDPID); + + if (out != stdout) + { + fclose (out); + if (out_file_dirty != 1) + remove (out_name); + } + + if (err != stderr) + { + fclose (err); + if (err_file_dirty != 1) + remove (err_name); + } + + pthread_mutex_destroy (&lock); +} + +void +__mpxrt_write_uint (verbose_type vt, uint64_t val, unsigned base) +{ + static const char digits[] = { + '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; + char str[65]; + int len = 0; + + if (vt > verbose_val || base <= 1 || base > sizeof (digits)) + return; + + if (val < base) + str[len++] = digits[val]; + else + while (val) + { + str[len++] = digits[val % base]; + val = val / base; + } + str[len++] = 0; + + __mpxrt_write (vt, str); +} + +void +__mpxrt_write (verbose_type vt, const char* str) +{ + va_list argp; + FILE *print_to; + + if (vt > verbose_val) + return; + + if (vt == VERB_ERROR) + { + print_to = err; + err_file_dirty = 1; + } + else + { + print_to = out; + out_file_dirty = 1; + } + pthread_mutex_lock (&lock); + write (fileno (print_to), str, strlen (str)); + pthread_mutex_unlock (&lock); + va_end (argp); +} + +void +__mpxrt_print (verbose_type vt, const char* frmt, ...) +{ + va_list argp; + FILE *print_to; + + if (vt > verbose_val) + return; + + va_start (argp, frmt); + if (vt == VERB_ERROR) + { + print_to = err; + err_file_dirty = 1; + } + else + { + print_to = out; + out_file_dirty = 1; + } + pthread_mutex_lock (&lock); + vfprintf (print_to, frmt, argp); + fflush (print_to); + pthread_mutex_unlock (&lock); + va_end (argp); +} + +mpx_rt_mode_t +__mpxrt_mode (void) +{ + return mode; +} + +void +__mpxrt_print_summary (uint64_t num_brs, uint64_t l1_size) +{ + + if (summary == 0) + return; + + out_file_dirty = 1; + + pthread_mutex_lock (&lock); + fprintf (out, "MPX runtime summary:\n"); + fprintf (out, " Number of bounds violations: %" PRIu64 ".\n", num_brs); + fprintf (out, " Size of allocated L1: %" PRIu64 "B\n", l1_size); + fflush (out); + pthread_mutex_unlock (&lock); +} diff --git a/libmpx/mpxrt/mpxrt-utils.h b/libmpx/mpxrt/mpxrt-utils.h new file mode 100644 index 0000000..a8380a5 --- /dev/null +++ b/libmpx/mpxrt/mpxrt-utils.h @@ -0,0 +1,65 @@ +/* mpxrt-utils.h -*-C++-*- + * + ************************************************************************* + * + * @copyright + * Copyright (C) 2014, Intel Corporation + * All rights reserved. + * + * @copyright + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * @copyright + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY + * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************/ + +#ifndef MPXRT_UTILS_H +#define MPXRT_UTILS_H + +#include + +typedef enum { + VERB_ERROR, + VERB_INFO, + VERB_BR, + VERB_DEBUG +} verbose_type; + +typedef enum { + MPX_RT_COUNT, + MPX_RT_STOP +} mpx_rt_mode_t; + +void __mpxrt_init_env_vars (int* bndpreserve, int *enable); +void __mpxrt_write_uint (verbose_type vt, uint64_t val, unsigned base); +void __mpxrt_write (verbose_type vt, const char* str); +void __mpxrt_print (verbose_type vt, const char* frmt, ...); +mpx_rt_mode_t __mpxrt_mode (void); +void __mpxrt_utils_free (void); +void __mpxrt_print_summary (uint64_t num_brs, uint64_t l1_size); + +#endif /* MPXRT_UTILS_H */ diff --git a/libmpx/mpxrt/mpxrt.c b/libmpx/mpxrt/mpxrt.c new file mode 100644 index 0000000..55bfcf4 --- /dev/null +++ b/libmpx/mpxrt/mpxrt.c @@ -0,0 +1,505 @@ +/* mpxrt.c -*-C++-*- + * + ************************************************************************* + * + * @copyright + * Copyright (C) 2014, Intel Corporation + * All rights reserved. + * + * @copyright + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * @copyright + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY + * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************/ + +#define __STDC_FORMAT_MACROS +#include "config.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "mpxrt-utils.h" + +#ifdef __i386__ + +/* i386 directory size is 4MB */ +#define NUM_L1_BITS 20 + +#define REG_IP_IDX REG_EIP +#define REX_PREFIX + +#define XSAVE_OFFSET_IN_FPMEM sizeof (struct _libc_fpstate) + +#else /* __i386__ */ + +/* x86_64 directory size is 2GB */ +#define NUM_L1_BITS 28 + +#define REG_IP_IDX REG_RIP +#define REX_PREFIX "0x48, " + +#define XSAVE_OFFSET_IN_FPMEM 0 + +#endif /* !__i386__ */ + +#define MPX_ENABLE_BIT_NO 0 +#define BNDPRESERVE_BIT_NO 1 + +const size_t MPX_L1_SIZE = (1UL << NUM_L1_BITS) * sizeof (void *); + +struct xsave_hdr_struct +{ + uint64_t xstate_bv; + uint64_t reserved1[2]; + uint64_t reserved2[5]; +} __attribute__ ((packed)); + +struct bndregs_struct +{ + uint64_t bndregs[8]; +} __attribute__ ((packed)); + +struct bndcsr_struct { + uint64_t cfg_reg_u; + uint64_t status_reg; +} __attribute__((packed)); + +struct xsave_struct +{ + uint8_t fpu_sse[512]; + struct xsave_hdr_struct xsave_hdr; + uint8_t ymm[256]; + uint8_t lwp[128]; + struct bndregs_struct bndregs; + struct bndcsr_struct bndcsr; +} __attribute__ ((packed)); + +/* Following vars are initialized at process startup only + and thus are considered to be thread safe. */ +static void *l1base = NULL; +static int bndpreserve; +static int enable; + +/* Var holding number of occured BRs. It is modified from + signal handler only and thus it should be thread safe. */ +static uint64_t num_bnd_chk = 0; + +static inline void +xrstor_state (struct xsave_struct *fx, uint64_t mask) +{ + uint32_t lmask = mask; + uint32_t hmask = mask >> 32; + + asm volatile (".byte " REX_PREFIX "0x0f,0xae,0x2f\n\t" + : : "D" (fx), "m" (*fx), "a" (lmask), "d" (hmask) + : "memory"); +} + +static inline void +xsave_state (struct xsave_struct *fx, uint64_t mask) +{ + uint32_t lmask = mask; + uint32_t hmask = mask >> 32; + + asm volatile (".byte " REX_PREFIX "0x0f,0xae,0x27\n\t" + : : "D" (fx), "m" (*fx), "a" (lmask), "d" (hmask) + : "memory"); +} + +static inline uint64_t +xgetbv (uint32_t index) +{ + uint32_t eax, edx; + + asm volatile (".byte 0x0f,0x01,0xd0" /* xgetbv */ + : "=a" (eax), "=d" (edx) + : "c" (index)); + return eax + ((uint64_t)edx << 32); +} + +static uint64_t +read_mpx_status_sig (ucontext_t *uctxt) +{ + uint8_t __attribute__ ((__aligned__ (64))) buffer[4096]; + struct xsave_struct *xsave_buf = (struct xsave_struct *)buffer; + + memset (buffer, 0, sizeof (buffer)); + memcpy (buffer, + (uint8_t *)uctxt->uc_mcontext.fpregs + XSAVE_OFFSET_IN_FPMEM, + sizeof (struct xsave_struct)); + return xsave_buf->bndcsr.status_reg; +} + +static uint8_t * +get_next_inst_ip (uint8_t *addr) +{ + uint8_t *ip = addr; + uint8_t sib; + + /* determine the prefix. */ + switch (*ip) + { + case 0xf2: + case 0xf3: + case 0x66: + ip++; + break; + } + + /* look for rex prefix */ + if ((*ip & 0x40) == 0x40) + ip++; + + /* Make sure we have a MPX instruction. */ + if (*ip++ != 0x0f) + return addr; + + /* Skip the op code byte. */ + ip++; + + /* Get the moderm byte. */ + uint8_t modrm = *ip++; + + /* Break it down into parts. */ + uint8_t rm = modrm & 7; + uint8_t mod = (modrm >> 6); + + /* Init the parts of the address mode. */ + uint8_t base = 8; + + /* Is it a mem mode? */ + if (mod != 3) + { + /* look for scaled indexed addressing */ + if (rm == 4) + { + /* SIB addressing */ + sib = *ip++; + base = sib & 7; + switch (mod) + { + case 0: + if (base == 5) + ip += 4; + break; + + case 1: + ip++; + break; + + case 2: + ip += 4; + break; + } + } + else + { + /* MODRM addressing */ + switch (mod) + { + case 0: + if (rm == 5) + /* DISP32 addressing, no base */ + ip += 4; + break; + + case 1: + ip++; + break; + + case 2: + ip += 4; + break; + } + } + } + return ip; +} + +static void +handler (int sig __attribute__ ((unused)), + siginfo_t *info __attribute__ ((unused)), + void *vucontext, + struct xsave_struct *buf __attribute__ ((unused))) +{ + ucontext_t* uctxt; + greg_t trapno; + greg_t ip; + + uctxt = vucontext; + trapno = uctxt->uc_mcontext.gregs[REG_TRAPNO]; + ip = uctxt->uc_mcontext.gregs[REG_IP_IDX]; + + if (trapno == 5) + { + uint64_t status = read_mpx_status_sig (uctxt); + uint64_t br_reason = status & 0x3; + + __mpxrt_write (VERB_BR, "Saw a #BR! status "); + __mpxrt_write_uint (VERB_BR, status, 10); + __mpxrt_write (VERB_BR, " at 0x"); + __mpxrt_write_uint (VERB_BR, ip, 16); + __mpxrt_write (VERB_BR, "\n"); + + switch (br_reason) + { + case 1: /* traditional BR */ + num_bnd_chk++; + uctxt->uc_mcontext.gregs[REG_IP_IDX] = + (greg_t)get_next_inst_ip ((uint8_t *)ip); + if (__mpxrt_mode () == MPX_RT_STOP) + exit (255); + return; + + default: + __mpxrt_write (VERB_BR, "Unexpected status with bound exception: "); + __mpxrt_write_uint (VERB_BR, status, 10); + __mpxrt_write (VERB_BR, "\n"); + break; + } + } + else if (trapno == 14) + { + __mpxrt_write (VERB_ERROR, "In signal handler, trapno = "); + __mpxrt_write_uint (VERB_ERROR, trapno, 10); + __mpxrt_write (VERB_ERROR, ", ip = 0x"); + __mpxrt_write_uint (VERB_ERROR, ip, 16); + __mpxrt_write (VERB_BR, "\n"); + exit (255); + } + else + { + __mpxrt_write (VERB_ERROR, "Unexpected trap "); + __mpxrt_write_uint (VERB_ERROR, trapno, 10); + __mpxrt_write (VERB_ERROR, "! at 0x"); + __mpxrt_write_uint (VERB_ERROR, ip, 16); + __mpxrt_write (VERB_BR, "\n"); + exit (255); + } +} + +/* + * using wrapper to the real handler in order to save the bnd regs + * using xsave before any unprefixed call. an unprefixed call to + * __i686.get_pc_thunk.bx is added by the linker in 32bit at the + * beginning of handler function since there are references to + * global variables. + */ +static void +handler_wrap (int signum, siginfo_t* si, void* vucontext) +{ + /* + * Since the OS currently not handling chkptr regs. + * We need to store them for later use. They might be + * init due to unprefixed call,Jcc,ret. avoiding calling + * function since the function will be unprefixed as well. + */ + uint8_t __attribute__ ((__aligned__ (64))) buffer[4096]; + struct xsave_struct *xsave_buf = (struct xsave_struct *)buffer; + uint64_t mask = 0x18; + uint32_t lmask = mask; + uint32_t hmask = mask >> 32; + + asm volatile (".byte " REX_PREFIX "0x0f,0xae,0x27\n\t" + : : "D" (xsave_buf), "m" (*xsave_buf), + "a" (lmask), "d" (hmask) + : "memory"); + + handler (signum, si, vucontext, xsave_buf); +} + +static bool +check_mpx_support (void) +{ + unsigned int eax, ebx, ecx, edx; + unsigned int max_level = __get_cpuid_max (0, NULL); + + if (max_level < 13) + { + __mpxrt_print (VERB_DEBUG, "No required CPUID level support.\n"); + return false; + } + + __cpuid_count (0, 0, eax, ebx, ecx, edx); + if (!(ecx & bit_XSAVE)) + { + __mpxrt_print (VERB_DEBUG, "No XSAVE support.\n"); + return false; + } + + if (!(ecx & bit_OSXSAVE)) + { + __mpxrt_print (VERB_DEBUG, "No OSXSAVE support.\n"); + return false; + } + + __cpuid_count (7, 0, eax, ebx, ecx, edx); + if (!(ebx & bit_MPX)) + { + __mpxrt_print (VERB_DEBUG, "No MPX support.\n"); + return false; + } + + __cpuid_count (13, 0, eax, ebx, ecx, edx); + if (!(eax & bit_BNDREGS)) + { + __mpxrt_print (VERB_DEBUG, "No BNDREGS support.\n"); + return false; + } + + if (!(eax & bit_BNDCSR)) + { + __mpxrt_print (VERB_DEBUG, "No BNDCSR support.\n"); + return false; + } + + return true; +} + +static void +enable_mpx (void) +{ + uint8_t __attribute__ ((__aligned__ (64))) buffer[4096]; + struct xsave_struct *xsave_buf = (struct xsave_struct *)buffer; + + memset (buffer, 0, sizeof (buffer)); + xrstor_state (xsave_buf, 0x18); + + __mpxrt_print (VERB_DEBUG, "Initalizing MPX...\n"); + __mpxrt_print (VERB_DEBUG, " Enable bit: %d\n", enable); + __mpxrt_print (VERB_DEBUG, " BNDPRESERVE bit: %d\n", bndpreserve); + + /* Enable MPX */ + xsave_buf->xsave_hdr.xstate_bv = 0x10; + xsave_buf->bndcsr.cfg_reg_u = (unsigned long)l1base; + xsave_buf->bndcsr.cfg_reg_u |= enable << MPX_ENABLE_BIT_NO; + xsave_buf->bndcsr.cfg_reg_u |= bndpreserve << BNDPRESERVE_BIT_NO; + xsave_buf->bndcsr.status_reg = 0; + + xrstor_state (xsave_buf, 0x10); +} + +static bool +process_specific_init (void) +{ + if (!check_mpx_support ()) + return false; + + l1base = mmap (NULL, MPX_L1_SIZE, PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); + if (l1base == MAP_FAILED) + { + perror ("mmap"); + exit (EXIT_FAILURE); + } + + enable_mpx (); + + if (prctl (43)) + { + __mpxrt_print (VERB_ERROR, "No MPX support\n"); + return false; + } + + return true; +} + +static bool +process_specific_finish (void) +{ + if (!check_mpx_support ()) + return false; + + if (prctl (44)) + { + __mpxrt_print (VERB_ERROR, "No MPX support\n"); + return false; + } + + munmap (l1base, MPX_L1_SIZE); + + return true; +} + +static void +setup_handler (void) +{ + int r,rs; + struct sigaction newact; + + /* #BR is mapped to sigsegv */ + int signum = SIGSEGV; + + newact.sa_handler = 0; + newact.sa_sigaction = handler_wrap; + + /* sigset_t - signals to block while in the handler */ + /* get the old signal mask. */ + rs = sigprocmask (SIG_SETMASK, 0, &newact.sa_mask); + assert (rs == 0); + + /* call sa_sigaction, not sa_handler */ + newact.sa_flags = SA_SIGINFO; + /* + * in case we call user's handler on SIGSEGV (not bound + * violation exception) we want to allow bound checking + * inside the user handler -> nested exception + */ + newact.sa_flags |= SA_NODEFER; + + newact.sa_restorer = 0; + r = sigaction (signum, &newact, 0); + assert (r == 0); +} + +/* + * set constructor priority to two to make it run after the + * constructor in sigaction.c + */ +static void __attribute__ ((constructor (1005))) +mpxrt_prepare (void) +{ + __mpxrt_init_env_vars (&bndpreserve, &enable); + setup_handler (); + process_specific_init (); +} + +static void __attribute__ ((destructor)) +mpxrt_cleanup (void) +{ + __mpxrt_print_summary (num_bnd_chk, MPX_L1_SIZE); + __mpxrt_utils_free (); + process_specific_finish (); +}