[PATCH, MPX runtime 1/2] Integrate MPX runtime library

Ilya Enkovich enkovich.gnu@gmail.com
Fri Nov 21 16:04:00 GMT 2014


On 19 Nov 21:11, Ilya Enkovich wrote:
> 2014-11-19 20:55 GMT+03:00 Jeff Law <law@redhat.com>:
> > On 11/19/14 07:15, Ilya Enkovich wrote:
> >
> >> --
> >> 2014-11-19  Ilya Enkovich  <ilya.enkovich@intel.com>
> >>
> >>         * Makefile.def: Add libmpx.
> >>         * configure.ac: Add libmpx.
> >>         * Makefile.in: Regenerate.
> >>         * configure: Regenerate.
> >>
> >> gcc/
> >>
> >> 2014-11-19  Ilya Enkovich  <ilya.enkovich@intel.com>
> >>
> >>         * 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  <ilya.enkovich@intel.com>
> >>
> >>         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  <ilya.enkovich@intel.com>

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

gcc/

2014-11-21  Ilya Enkovich  <ilya.enkovich@intel.com>

	* 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  <ilya.enkovich@intel.com>

	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  <ilya.enkovich@intel.com>
+
+	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 <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..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 <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/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 <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;
+
+/* 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 <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_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 <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 <cpuid.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)
+
+#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 ();
+}



More information about the Gcc-patches mailing list