On 11 Nov 20:25, Joseph Myers wrote:
> On Tue, 11 Nov 2014, Andi Kleen wrote:
> 
> > Joseph Myers <jos...@codesourcery.com> writes:
> > 
> > > On Tue, 11 Nov 2014, Ilya Enkovich wrote:
> > >
> > >> Hi,
> > >> 
> > >> This patch integrates MPX runtime library into GCC source tree.  MPX 
> > >> runtime is responsible for initialization of MPX feature in HW, signal 
> > >> handling, reporting etc.  Library is linked to codes compiled with 
> > >> -mmpx.
> > >> 
> > >> Bootstrap is OK for x86_64-unknown-linux-gnu.  OK for trunk?
> > >
> > > Please use symbol versioning to control the set of exports for the 
> > > library; only symbols explicitly listed to be exported at a given symbol 
> > > version should be exported.
> > 
> > Also I think you need some user documentation on the implications of the
> > overriding of sigaction. If someone else wants to do similar tricks (and
> > I'm sure some do) there would be conflicts.
> 
> Indeed, I don't understand what the purpose of this overriding is.  What 
> goes wrong if you just use default signal handling in a program built with 
> MPX, or don't handle any environment variables specially at all?  That is, 
> why does this need to be linked with all programs built with MPX at all, 
> rather than being optional functionality in an independent library that 
> people can choose to build and link with if they want that extra 
> functionality?

I think there was a historical reason to make such sigaction chain.  The same 
signal is used to report bounds violation and absence of Bounds Table.  
Initiail runtime version took care of it and managed Bounds Tables.  User may 
want to catch and handle bounds violation by himsel but doubtedly he wants to 
manage Bounds Tables as well.  Thus such chain was usefull.

Currently Bounds Table management is performed in kernel and signal handler 
only handles bounds violation.  It means I may just register MPX runtime 
handler as a default one and if user wants to override it later - it's OK.  I 
remove these mpxrt-sigaction.* files from runtime and just use regular 
sigaction.

BTW no sigaction override means it should work for -static.  I'll test it and 
fix link specs appropriately soon.

MPX runtime needs to be linked with programs using MPX because it initializes 
hardware.  Without it all MPX instructions are just NOPs.  Thus it's not an 
extra functionality, but is for basic MPX functionality.

> 
> My starting point is that MPX provides functionality for detecting certain 
> cases of undefined behavior in C that wouldn't otherwise be detected, and 
> it should be possible to use with any C program (including ISO C ones that 
> don't use POSIX interfaces such as sigaction and may use the sigaction 
> identifier for some other purpose).
> 
> Another issue: handle_sigsegv calls functions documented in the glibc 
> manual as AS-unsafe, such as pthread_setspecific and (via do_exit) 
> fprintf.  You need to make sure everything called from a signal handler is 
> AS-safe.
> 
> -- 
> Joseph S. Myers
> jos...@codesourcery.com

I also fixed other issues you mentioned in your previous comments.  Below is a 
new version.  Does it look better?

Thanks,
Ilya
--
2014-11-12  Ilya Enkovich  <ilya.enkov...@intel.com>

        * Makefile.def: Add libmpx.
        * configure.ac: Add libmpx.
        * Makefile.in: Regenerate.
        * configure: Regenerate.

gcc/

2014-11-12  Ilya Enkovich  <ilya.enkov...@intel.com>

        * gcc.c (MPX_SPEC): New.
        (LINK_COMMAND_SPEC): Add MPX_SPEC.

libmpx/

2014-11-12  Ilya Enkovich  <ilya.enkov...@intel.com>

        Initial commit.


diff --git a/Makefile.def b/Makefile.def
index dcbcd08..49e3c6f 100644
--- a/Makefile.def
+++ b/Makefile.def
@@ -133,6 +133,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 2f0af4a..95fbab1 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 \
@@ -572,6 +573,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-*-*)
@@ -2612,6 +2632,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/gcc.c b/gcc/gcc.c
index e013d52..200704b 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -804,6 +804,13 @@ proper position among the other output files.  */
     %{fvtable-verify=preinit: -lvtv -u_vtable_map_vars_start 
-u_vtable_map_vars_end}}"
 #endif
 
+#ifndef MPX_SPEC
+#define MPX_SPEC "\
+%{!nostdlib:%{!nodefaultlibs:%{mmpx:\
+    %{static:%nMPX runtime is disabled due to -static used}\
+    %{!static:-lmpx}}}}"
+#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.  */
@@ -824,6 +831,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  <ilya.enkov...@intel.com>
+
+       Initial checkin.
diff --git a/libmpx/Makefile.am b/libmpx/Makefile.am
new file mode 100644
index 0000000..c6b479f
--- /dev/null
+++ b/libmpx/Makefile.am
@@ -0,0 +1,41 @@
+ACLOCAL_AMFLAGS = -I .. -I ../config
+
+SUBDIRS = mpxrt
+
+# 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 <conftest.tar])
+    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/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 <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the <memory.h> 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 <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/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 <unistd.h> 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..9a761c4
--- /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="-ldl -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])
+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 <http://www.gnu.org/licenses/>.
+
+# 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/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..4b203b6
--- /dev/null
+++ b/libmpx/mpxrt/Makefile.am
@@ -0,0 +1,39 @@
+## Makefile for the Intel MPX runtime library.
+##
+## Copyright (C) 2014 Free Software Foundation, Inc.
+##
+## Process this file with automake to produce Makefile.in.
+##
+## This file is part of the Intel MPX run-time 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.
+
+## You should have received a copy of the GNU General Public License
+## along with this library; see the file COPYING3.  If not see
+## <http://www.gnu.org/licenses/>.
+
+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_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` 
$(link_libmpx)
+
+mpxrt.lo: mpxrt-utils.h
+mpxrt-utils.lo: mpxrt-utils.h
+endif
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..b21b31b
--- /dev/null
+++ b/libmpx/mpxrt/mpxrt-utils.c
@@ -0,0 +1,471 @@
+/* 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 <inttypes.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include <pthread.h>
+#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;
+
+static FILE *out;
+static FILE *err;
+static char out_name[MAX_FILE_NAME];
+static char err_name[MAX_FILE_NAME];
+static int out_file_dirty;
+static int err_file_dirty;
+static verbose_type verbose_val;
+static int add_pid;
+static int summary;
+static int files_overwritten;
+static mpx_rt_mode_t mode;
+static pthread_mutex_t lock;
+static env_var_list_t env_var_list;
+
+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_BNDPRESERVE, 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_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);
+  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;
+
+  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);
+}
diff --git a/libmpx/mpxrt/mpxrt-utils.h b/libmpx/mpxrt/mpxrt-utils.h
new file mode 100644
index 0000000..06ca65e
--- /dev/null
+++ b/libmpx/mpxrt/mpxrt-utils.h
@@ -0,0 +1,63 @@
+/* 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 <stdint.h>
+
+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_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..b4b4012
--- /dev/null
+++ b/libmpx/mpxrt/mpxrt.c
@@ -0,0 +1,502 @@
+/* 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 <inttypes.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <signal.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <sys/prctl.h>
+#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)
+
+static inline void
+__cpuid (unsigned int *eax, unsigned int *ebx,
+        unsigned int *ecx, unsigned int *edx)
+{
+  /* ecx is often an input as well as an output. */
+  asm volatile ("push %%ebx;"
+               "cpuid;"
+               "mov %%ebx, %1;"
+               "pop %%ebx"
+               : "=a" (*eax),
+                 "=g" (*ebx),
+                 "=c" (*ecx),
+                 "=d" (*edx)
+               : "0" (*eax), "2" (*ecx));
+}
+
+#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
+
+static inline void __cpuid (unsigned int *eax, unsigned int *ebx,
+                           unsigned int *ecx, unsigned int *edx)
+{
+  /* ecx is often an input as well as an output. */
+  asm volatile ("cpuid;"
+               : "=a" (*eax),
+                 "=b" (*ebx),
+                 "=c" (*ecx),
+                 "=d" (*edx)
+               : "0" (*eax), "2" (*ecx));
+}
+
+#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));
+
+static void *l1base = NULL;
+static int bndpreserve;
+static int enable;
+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_print (VERB_BR, "Saw a #BR! status %" PRIu64
+                    " at %016llx\n", status, ip);
+
+      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_print (VERB_BR,
+                        "Unexpected status with bound exception: %"PRIu64"\n",
+                        status);
+         break;
+       }
+    }
+  else if (trapno == 14)
+    {
+      __mpxrt_print (VERB_ERROR,
+                    "In signal handler, trapno = %d, ip = %016llx\n",
+                    trapno, ip);
+      exit (255);
+    }
+  else
+    {
+      __mpxrt_print (VERB_ERROR, "unexpected trap %d! at %016llx\n", trapno, 
ip);
+      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 inline void
+cpuid_count (unsigned int op, int count,
+            unsigned int *eax, unsigned int *ebx,
+            unsigned int *ecx, unsigned int *edx)
+{
+  *eax = op;
+  *ecx = count;
+  __cpuid (eax, ebx, ecx, edx);
+}
+
+static bool
+check_mpx_support (void)
+{
+  unsigned int eax, ebx, ecx, edx;
+
+  cpuid_count (1, 0, &eax, &ebx, &ecx, &edx);
+
+  if ((!(ecx & (1 << 26))) || (!(ecx & (1 << 27))))
+    return false;
+
+  cpuid_count (0, 0, &eax, &ebx, &ecx, &edx);
+
+  if (eax < 0xD)
+    return false;
+
+  cpuid_count (0xD, 0, &eax, &ebx, &ecx, &edx);
+
+  if ((eax & 0x18) != 0x18)
+    return false;
+
+  if ((xgetbv (0) & 0x18) != 0x18)
+    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 (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 ();
+}

Reply via email to