On Tue, Nov 11, 2014 at 4:34 PM, Ilya Enkovich <enkovich....@gmail.com> 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.
What happens if you omit -mmpx from the linker command-line? What happens if you mix -mmpx and non -mmpx objects? I wonder why this is not part of glibc and whether initialization is needed is communicated by some ELF flag in the executable/library which is determined by the linker. Richard. > Bootstrap is OK for x86_64-unknown-linux-gnu. OK for trunk? > > Thanks, > Ilya > -- > 2014-11-11 Ilya Enkovich <ilya.enkov...@intel.com> > > * Makefile.def: Add libmpx. > * configure.ac: Add libmpx. > * Makefile.in: Regenerate. > * configure: Regenerate. > > gcc/ > > 2014-11-11 Ilya Enkovich <ilya.enkov...@intel.com> > > * gcc.c (MPX_SPEC): New. > (LINK_COMMAND_SPEC): Add MPX_SPEC. > > libmpx/ > > 2014-11-11 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/configure.ac b/libmpx/configure.ac > new file mode 100644 > index 0000000..e017569 > --- /dev/null > +++ b/libmpx/configure.ac > @@ -0,0 +1,122 @@ > +# -*- 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 > + > +# 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_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..d896ca6 > --- /dev/null > +++ b/libmpx/mpxrt/Makefile.am > @@ -0,0 +1,40 @@ > +## 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)/../include > +AM_CFLAGS = $(XCFLAGS) > + > +toolexeclib_LTLIBRARIES = libmpx.la > + > +libmpx_la_SOURCES = mpxrt.c mpxrt-sigaction.c mpxrt-utils.c > + > +libmpx_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` > $(link_libmpx) > + > +mpxrt.lo: mpxrt-utils.h > +mpxrt-sigaction.lo: mpxrt-sigaction.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-sigaction.c b/libmpx/mpxrt/mpxrt-sigaction.c > new file mode 100644 > index 0000000..6b676f7 > --- /dev/null > +++ b/libmpx/mpxrt/mpxrt-sigaction.c > @@ -0,0 +1,151 @@ > +/* mpxrt-sigaction.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. > + * > + **************************************************************************/ > + > +#include "mpxrt-sigaction.h" > +#include <assert.h> > + > +#include <malloc.h> > +#include <stdio.h> > +#include <memory.h> > +#include <stdlib.h> > +#include <pthread.h> > + > +#define __USE_GNU > +#include <dlfcn.h> > + > +const static void* one = (void*)1; > +const static void* zero = (void*)0; > + > +typedef int (*sigact_fptr)(int, const struct sigaction *, struct sigaction > *); > + > +static struct sigaction old_sigaction; > + > +static sigact_fptr sigact_f = 0; > +static pthread_key_t tlsKey = 0; > + > +/* > + * Hide libc implementation. If sig num in not SIGSEGV call the > + * original sigaction. If sig num is SIGSEGV store the handler > + * for later calling. > + */ > +int > +sigaction (int sig, const struct sigaction *act, struct sigaction *oact) > +{ > + if (sig == SIGSEGV) > + { > + if (oact != 0) > + memcpy (oact, &old_sigaction, sizeof (struct sigaction)); > + > + if (act != 0) > + { > + memcpy (&old_sigaction, act, sizeof (struct sigaction)); > + return 0; > + } > + } > + else > + { > + assert (sigact_f != 0); > + return (*sigact_f)(sig, act, oact); > + } > +} > + > +/* > + * set handler for SIGSEGV signal. does not returns the oact to prevent > + * confusion in oact state. since we do not know what will be called > + * first app's sigaction or runtime's register_sigsegv. > + */ > +int > +register_sigsegv_handler (int sig, const struct sigaction *act) > +{ > + int res; > + > + assert (sig == SIGSEGV); > + assert (sigact_f != 0); > + > + return (*sigact_f) (sig, act, 0); > +} > + > +void > +do_exit (void) > +{ > + fprintf (stderr, "Segmentation fault\n"); > + exit (254); > +} > + > +/* trying to call the stored handler */ > +void > +handle_sigsegv (int signum, siginfo_t* si, void* vucontext) > +{ > + if (old_sigaction.sa_handler == SIG_IGN > + || old_sigaction.sa_handler == SIG_DFL) > + do_exit (); > + > + if (pthread_getspecific (tlsKey) == one) > + if((old_sigaction.sa_flags & SA_NODEFER) != SA_NODEFER) > + do_exit (); > + if ((old_sigaction.sa_flags & SA_SIGINFO) == SA_SIGINFO) > + { > + pthread_setspecific (tlsKey, one); > + (*old_sigaction.sa_sigaction) (signum, si, vucontext); > + } > + else > + { > + pthread_setspecific (tlsKey, one); > + (*old_sigaction.sa_handler) (signum); > + } > + pthread_setspecific (tlsKey,zero); > +} > + > +/* > + * set constructor priority to one to make it run before the > + * constructor in mpx_rt.c > + */ > +void __attribute__ ((constructor (1000))) > +mpx_sig_init (void) > +{ > + /* init old_sigaction to the default handler */ > + sigact_f = (sigact_fptr)dlsym (RTLD_NEXT, "sigaction"); > + if (sigact_f == 0) > + { > + fprintf (stderr, "ERROR: could not find function sigaction\n"); > + exit (1); > + } > + (*sigact_f) (SIGSEGV, 0, &old_sigaction); > + pthread_key_create (&tlsKey, 0); > +} > diff --git a/libmpx/mpxrt/mpxrt-sigaction.h b/libmpx/mpxrt/mpxrt-sigaction.h > new file mode 100644 > index 0000000..194304c > --- /dev/null > +++ b/libmpx/mpxrt/mpxrt-sigaction.h > @@ -0,0 +1,44 @@ > +/* mpxrt-sigaction.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. > + * > + **************************************************************************/ > + > +#include <signal.h> > + > +int sigaction (int sig, const struct sigaction *act, struct sigaction *oact); > +int register_sigsegv_handler (int sig, const struct sigaction *act); > +void handle_sigsegv (int signum, siginfo_t* si, void* vucontext); > diff --git a/libmpx/mpxrt/mpxrt-utils.c b/libmpx/mpxrt/mpxrt-utils.c > new file mode 100644 > index 0000000..73b1d2a > --- /dev/null > +++ b/libmpx/mpxrt/mpxrt-utils.c > @@ -0,0 +1,431 @@ > +/* 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. > + * > + **************************************************************************/ > + > +#include "mpxrt-utils.h" > +#include <stdio.h> > +#include <stdarg.h> > +#include <stdlib.h> > +#include <string.h> > +#include <limits.h> > +#include <pthread.h> > + > +#define OUT_ENV "CHKP_RT_OUT_FILE" > +#define ERR_ENV "CHKP_RT_ERR_FILE" > +#define MPX_RT_VERBOSE "CHKP_RT_VERBOSE" > +#define MPX_CHKPTR_MODE "CHKP_RT_MODE" > +#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_DEFUALT 0 > +#define MPX_RT_BNDPRESERVE_DEFUALT_STR "0" > +#define MPX_RT_PRINT_SUMMARY "CHKP_RT_PRINT_SUMMARY" > +#define MPX_RT_MEMORY_UPPER_LIMIT "CHKP_RT_MEMORY_UPPER_LIMIT" > + > +#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 int verbose_val; > +static int add_pid; > +static int summary; > +static int files_overwritten; > +static long mem_upper_limit; > +static mpx_rt_mode_t mode; > +static pthread_mutex_t lock; > +static env_var_list_t env_var_list; > + > +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 (sizeof (env_var_t)); > + n->env_name = (char *)malloc (strlen (env) + 1); > + n->env_val = (char *)malloc (strlen (val) + 1); > + > + strcpy (n->env_name, env); > + strcpy (n->env_val, val); > + > + n->next = 0; > + > + 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; > +} > + > +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 (); > + sprintf (file_name, "%s.%d", env, pid); > + } > + else > + sprintf (file_name, "%s", env); > + > + *file = fopen (file_name, "w"); > + 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 = getenv (OUT_ENV); > + err_env = getenv (ERR_ENV); > + > + if (add_pid == 0 && (out_env!=0 || err_env!=0)) { > + fprintf(stderr, "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 () > +{ > + char *out_env; > + char *err_env; > + > + out_env = getenv (OUT_ENV); > + err_env = getenv (ERR_ENV); > + > + if (add_pid == 0 && (out_env != 0 || err_env != 0)) > + files_overwritten = 1; > +} > + > +static verbose_type > +set_mpx_rt_mode (const char *env) > +{ > + if (env == 0) > + return MPX_RT_COUNT; > + else if (strcmp(env, "stop") == 0) > + return MPX_RT_STOP; > + else if (strcmp(env,"count") == 0) > + return MPX_RT_COUNT; > + > + fprintf (out, "Illegal value '%s' for %s. Legal values are [stop | > count]\n", > + env, MPX_CHKPTR_MODE); > + > + exit(1); > +} > + > +static void > +print_help () > +{ > + fprintf (out, "Point Lookout Runtime environment variables help.\n"); > + > + fprintf (out, "%s \t set output file for info & debug [default: stdout]\n", > + OUT_ENV); > + fprintf (out, "%s \t set output file for error [default: stderr]\n", > ERR_ENV); > + 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, VERB_BR); > + fprintf (out, "%s \t\t set mpx runtime behavior on #BR exception." > + " [stop,count]\n" > + "\t\t\t [default: count]\n", MPX_CHKPTR_MODE); > + 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: %s]\n", MPX_RT_BNDPRESERVE, > + MPX_RT_BNDPRESERVE_DEFUALT_STR); > + fprintf (out, "%s \t print summary at the end of the run\n" > + "\t\t\t [default: yes]\n", MPX_RT_PRINT_SUMMARY); > + fprintf (out, "%s \t\t set mpx related physical memory upper limit\n" > + "\t\t\t [default: 0]\n", MPX_RT_MEMORY_UPPER_LIMIT); > + > + fprintf (out, "%s \t\t print this help and exit.\n" > + "\t\t\t [default: no]\n", MPX_RT_HELP); > + > + exit (0); > +} > + > +static int > +validate_bndpreserve (const char* env, int* bndpreserve) > +{ > + if (env == 0) > + { > + bndpreserve = MPX_RT_BNDPRESERVE_DEFUALT; > + return 1; > + } > + > + if (strcmp(env, "0") == 0) > + { > + *bndpreserve = 0; > + return 1; > + } > + > + if (strcmp(env, "1") == 0) > + { > + *bndpreserve = 1; > + return 1; > + } > + > + fprintf (out, "Illegal value '%s' for %s. Legal values are [0 | 1]\n", > + env, MPX_RT_BNDPRESERVE); > + > + return 0; > +} > + > +static int > +init_verbose_val (const char* env) > +{ > + if (env == 0) > + return VERB_BR; > + else if (strcmp(env, "0") == 0) > + return 0; > + else if (strcmp(env, "1") == 0) > + return 1; > + else if (strcmp(env, "2") == 0) > + return 2; > + else if (strcmp(env, "3") == 0) > + return 3; > + > + fprintf(out, "Illegal value '%s' for %s. Legal values are [0..3]\n", > + env, MPX_RT_VERBOSE); > + > + return 0; > +} > + > + > +void > +mpxrt_init_env_vars (int* bndpreserve) > +{ > + char *out_env; > + char *err_env; > + char *env; > + int res; > + > + pthread_mutex_init (&lock, NULL); > + > + out_env = getenv (OUT_ENV); > + env_var_list_add (OUT_ENV, out_env); > + > + err_env = getenv (ERR_ENV); > + env_var_list_add (ERR_ENV, err_env); > + > + env = getenv (MPX_RT_ADDPID); > + env_var_list_add (MPX_RT_ADDPID, env); > + > + if (env != 0) > + add_pid = 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; > + > + env = getenv (MPX_RT_VERBOSE); > + env_var_list_add (MPX_RT_VERBOSE, env); > + verbose_val = init_verbose_val (env); > + > + env = getenv (MPX_CHKPTR_MODE); > + env_var_list_add (MPX_CHKPTR_MODE, env); > + mode = set_mpx_rt_mode (env); > + > + env = getenv (MPX_RT_BNDPRESERVE); > + env_var_list_add (MPX_RT_BNDPRESERVE, env); > + res = validate_bndpreserve (env, bndpreserve); > + if (res == 0) > + exit (1); > + > + env = getenv (MPX_RT_MEMORY_UPPER_LIMIT); > + env_var_list_add (MPX_RT_MEMORY_UPPER_LIMIT, env); > + mem_upper_limit = 0; > + if (env) > + { > + mem_upper_limit = atol (env); > + if (mem_upper_limit < 0) > + mem_upper_limit = 0; > + } > + > + env = getenv (MPX_RT_PRINT_SUMMARY); > + summary = 1; > + if (env && strcmp (env, "yes") != 0) > + { > + summary = 0; > + env_var_list_add (MPX_RT_PRINT_SUMMARY, env); > + } > + > + env = getenv (MPX_RT_HELP); > + if (env && strcmp (env, "yes") == 0) > + 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); > +} > + > +void mpxrt_utils_free () > +{ > + if (files_overwritten) > + fprintf(out,"\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 () > +{ > + return mode; > +} > + > +static void > +env_var_print_summary () > +{ > + env_var_t* node; > + > + fprintf (out,"\nUsed environment variables:\n"); > + > + node = env_var_list.first; > + while (node != 0) > + { > + fprintf (out, "%s = %s\n", node->env_name, node->env_val); > + node = node->next; > + } > + out_file_dirty = 1; > +} > + > +void > +mpxrt_print_summary (uint64_t num_brs,uint64_t l1_size) > +{ > + > + if (summary == 0) > + return; > + > + fprintf (out, "\nPoint Lookout run time summary:\n"); > + fprintf (out, "number of BRs: %lld.\n", num_brs); > + fprintf (out, "size of allocated L1: %uB\n", l1_size); > + > + env_var_print_summary (); > +} > diff --git a/libmpx/mpxrt/mpxrt-utils.h b/libmpx/mpxrt/mpxrt-utils.h > new file mode 100644 > index 0000000..2dc3e45 > --- /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); > +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..b9bd2bd > --- /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 _GNU_SOURCE > +#include <stdio.h> > +#include <string.h> > +#include <stdint.h> > +#include <stdbool.h> > +#include <signal.h> > +#include <assert.h> > +#include <stdlib.h> > +#include <ucontext.h> > +#include <fcntl.h> > +#include <sys/mman.h> > +#include <sys/ipc.h> > +#include <sys/shm.h> > + > +#include "mpxrt-utils.h" > + > +#ifdef __i386__ > + > +/* i386 directory size is 4MB */ > +#define NUM_L1_BITS 20 > +#define NUM_L2_BITS 10 > +#define NUM_IGN_BITS 2 > +#define MPX_L2_NODE_ADDR_MASK 0xfffffffcUL > + > +#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 NUM_L2_BITS 17 > +#define NUM_IGN_BITS 3 > +#define MPX_L2_NODE_ADDR_MASK 0xfffffffffffffff8ULL > + > +#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 BNDSTA_ADDR_MASK 0xfffffffffffffffcULL > +#define BNDSTA_REASON_MASK 0xfffffffffffffffcULL > +#define BNDPRESERVE_BIT 1 > + > +typedef unsigned long ULONG; > + > +const ULONG MPX_L1_SIZE = (1UL << NUM_L1_BITS) * sizeof (ULONG); > +const ULONG MPX_MAX_L1_INDEX = (1UL << NUM_L1_BITS); > +const ULONG MPX_L2_NODE_SIZE = (1UL << NUM_L2_BITS) * (sizeof (ULONG) * 4); > + > +static int bndpreserve; > + > +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)); > + > +void *l1base = NULL; > + > +uint8_t __attribute__ ((__aligned__ (64))) buffer[4096]; > +struct xsave_struct *xsave_buf = (struct xsave_struct *)buffer; > + > +uint64_t num_bnd_chk = 0; > + > +#define handle_error(msg) \ > + do { perror (msg); exit (EXIT_FAILURE); } while (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) > +{ > + 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++; > + uint8_t ss = sib >> 6; > + 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 signum, siginfo_t* si, void* vucontext, > + struct xsave_struct *xsave_buf) > +{ > + 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_DEBUG, "Saw a #BR! status 0x%llx 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_ERROR,"Unexpected status with bound > exception:%llx\n", > + status); > + break; > + } > + } > + else if (trapno == 14) > + mpxrt_print (VERB_ERROR, "In signal handler, trapno = %d, ip = > %016llx\n", > + trapno, ip); > + else > + mpxrt_print (VERB_ERROR, "unexpected trap %d! at %016llx\n", trapno, ip); > + > + handle_sigsegv (signum, si, vucontext); > +} > + > +/* > + * 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. > + */ > +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); > +} > + > +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; > +} > + > +void > +enable_mpx (void* l1base) > +{ > + /* enable point lookup */ > + memset (buffer, 0, sizeof (buffer)); > + xrstor_state (xsave_buf, 0x18); > + > + xsave_buf->xsave_hdr.xstate_bv = 0x10; > + xsave_buf->bndcsr.cfg_reg_u = (unsigned long)l1base | 1; > + xsave_buf->bndcsr.status_reg = 0; > + > + xrstor_state (xsave_buf, 0x10); > +} > + > +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) > + { > + handle_error ("mmap"); > + return false; > + } > + > + enable_mpx (l1base); > + > + if (prctl (43)) > + { > + mpxrt_print (VERB_ERROR, "no MPX support\n"); > + return false; > + } > + > + return true; > +} > + > +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; > +} > + > +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 = register_sigsegv_handler (signum, &newact); > + assert (r == 0); > +} > + > +/* > + * set constructor priority to two to make it run after the > + * constructor in sigaction.c > + */ > +void __attribute__ ((constructor (1005))) mpx_prepare (void) > +{ > + mpxrt_init_env_vars (&bndpreserve); > + mpxrt_print (VERB_DEBUG, "mpx: hello...\n"); > + setup_handler (); > + process_specific_init (); > +} > + > +void __attribute__ ((destructor)) mpx_cleanup (void) > +{ > + mpxrt_print_summary (num_bnd_chk, MPX_L1_SIZE); > + mpxrt_utils_free (); > + process_specific_finish (); > +} > +