This commit was manufactured by cvs2svn to create tag 'MainlineMerge'.
llvm-svn: 87542
diff --git a/safecode/autoconf/configure.ac b/safecode/autoconf/configure.ac
index a132049..0de9cb0 100755
--- a/safecode/autoconf/configure.ac
+++ b/safecode/autoconf/configure.ac
@@ -57,7 +57,6 @@
dnl **************************************************************************
dnl * Checks for library functions.
dnl **************************************************************************
-AC_CHECK_FUNCS([posix_memalign ])
dnl **************************************************************************
dnl * Enable various compile-time options
diff --git a/safecode/configure b/safecode/configure
index 56440a8..e46f950 100755
--- a/safecode/configure
+++ b/safecode/configure
@@ -274,7 +274,7 @@
PACKAGE_BUGREPORT='dhurjati@cs.uiuc.edu'
ac_unique_file=""Makefile.common.in""
-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS LLVM_SRC LLVM_OBJ OMEGA CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT poolallocsrcdir poolallocobjdir LIBOBJS LTLIBOBJS'
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS LLVM_SRC LLVM_OBJ OMEGA poolallocsrcdir poolallocobjdir LIBOBJS LTLIBOBJS'
ac_subst_files=''
# Initialize some variables set by options.
@@ -715,22 +715,6 @@
ac_env_target_alias_value=$target_alias
ac_cv_env_target_alias_set=${target_alias+set}
ac_cv_env_target_alias_value=$target_alias
-ac_env_CC_set=${CC+set}
-ac_env_CC_value=$CC
-ac_cv_env_CC_set=${CC+set}
-ac_cv_env_CC_value=$CC
-ac_env_CFLAGS_set=${CFLAGS+set}
-ac_env_CFLAGS_value=$CFLAGS
-ac_cv_env_CFLAGS_set=${CFLAGS+set}
-ac_cv_env_CFLAGS_value=$CFLAGS
-ac_env_LDFLAGS_set=${LDFLAGS+set}
-ac_env_LDFLAGS_value=$LDFLAGS
-ac_cv_env_LDFLAGS_set=${LDFLAGS+set}
-ac_cv_env_LDFLAGS_value=$LDFLAGS
-ac_env_CPPFLAGS_set=${CPPFLAGS+set}
-ac_env_CPPFLAGS_value=$CPPFLAGS
-ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set}
-ac_cv_env_CPPFLAGS_value=$CPPFLAGS
#
# Report the --help message.
@@ -814,17 +798,6 @@
--with-poolalloc-srcdir Specify location of Pool Allocation source code
--with-poolalloc-objdir Specify location of Pool Allocation object code
-Some influential environment variables:
- CC C compiler command
- CFLAGS C compiler flags
- LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
- nonstandard directory <lib dir>
- CPPFLAGS C/C++ preprocessor flags, e.g. -I<include dir> if you have
- headers in a nonstandard directory <include dir>
-
-Use these variables to override the choices made by `configure' or to help
-it to find libraries and programs with nonstandard names/locations.
-
Report bugs to <dhurjati@cs.uiuc.edu>.
_ACEOF
fi
@@ -1407,1039 +1380,6 @@
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
-set dummy ${ac_tool_prefix}gcc; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_CC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_prog_CC="${ac_tool_prefix}gcc"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
- echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6
-else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
-fi
-if test -z "$ac_cv_prog_CC"; then
- ac_ct_CC=$CC
- # Extract the first word of "gcc", so it can be a program name with args.
-set dummy gcc; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$ac_ct_CC"; then
- ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_prog_ac_ct_CC="gcc"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
- echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
-echo "${ECHO_T}$ac_ct_CC" >&6
-else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
- CC=$ac_ct_CC
-else
- CC="$ac_cv_prog_CC"
-fi
-
-if test -z "$CC"; then
- if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
-set dummy ${ac_tool_prefix}cc; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_CC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_prog_CC="${ac_tool_prefix}cc"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
- echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6
-else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
-fi
-if test -z "$ac_cv_prog_CC"; then
- ac_ct_CC=$CC
- # Extract the first word of "cc", so it can be a program name with args.
-set dummy cc; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$ac_ct_CC"; then
- ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_prog_ac_ct_CC="cc"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
- echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
-echo "${ECHO_T}$ac_ct_CC" >&6
-else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
- CC=$ac_ct_CC
-else
- CC="$ac_cv_prog_CC"
-fi
-
-fi
-if test -z "$CC"; then
- # Extract the first word of "cc", so it can be a program name with args.
-set dummy cc; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_CC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
- ac_prog_rejected=no
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
- ac_prog_rejected=yes
- continue
- fi
- ac_cv_prog_CC="cc"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-
-if test $ac_prog_rejected = yes; then
- # We found a bogon in the path, so make sure we never use it.
- set dummy $ac_cv_prog_CC
- shift
- if test $# != 0; then
- # We chose a different compiler from the bogus one.
- # However, it has the same basename, so the bogon will be chosen
- # first if we set CC to just the basename; use the full file name.
- shift
- ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
- fi
-fi
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
- echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6
-else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
-fi
-if test -z "$CC"; then
- if test -n "$ac_tool_prefix"; then
- for ac_prog in cl
- do
- # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
-set dummy $ac_tool_prefix$ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_CC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
- echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6
-else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
- test -n "$CC" && break
- done
-fi
-if test -z "$CC"; then
- ac_ct_CC=$CC
- for ac_prog in cl
-do
- # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$ac_ct_CC"; then
- ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_prog_ac_ct_CC="$ac_prog"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
- echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
-echo "${ECHO_T}$ac_ct_CC" >&6
-else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
- test -n "$ac_ct_CC" && break
-done
-
- CC=$ac_ct_CC
-fi
-
-fi
-
-
-test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
-See \`config.log' for more details." >&5
-echo "$as_me: error: no acceptable C compiler found in \$PATH
-See \`config.log' for more details." >&2;}
- { (exit 1); exit 1; }; }
-
-# Provide some information about the compiler.
-echo "$as_me:$LINENO:" \
- "checking for C compiler version" >&5
-ac_compiler=`set X $ac_compile; echo $2`
-{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
- (eval $ac_compiler --version </dev/null >&5) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }
-{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
- (eval $ac_compiler -v </dev/null >&5) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }
-{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
- (eval $ac_compiler -V </dev/null >&5) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }
-
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-ac_clean_files_save=$ac_clean_files
-ac_clean_files="$ac_clean_files a.out a.exe b.out"
-# Try to create an executable without -o first, disregard a.out.
-# It will help us diagnose broken compilers, and finding out an intuition
-# of exeext.
-echo "$as_me:$LINENO: checking for C compiler default output file name" >&5
-echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6
-ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
-if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5
- (eval $ac_link_default) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; then
- # Find the output, starting from the most likely. This scheme is
-# not robust to junk in `.', hence go to wildcards (a.*) only as a last
-# resort.
-
-# Be careful to initialize this variable, since it used to be cached.
-# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile.
-ac_cv_exeext=
-# b.out is created by i960 compilers.
-for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out
-do
- test -f "$ac_file" || continue
- case $ac_file in
- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj )
- ;;
- conftest.$ac_ext )
- # This is the source file.
- ;;
- [ab].out )
- # We found the default executable, but exeext='' is most
- # certainly right.
- break;;
- *.* )
- ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
- # FIXME: I believe we export ac_cv_exeext for Libtool,
- # but it would be cool to find out if it's true. Does anybody
- # maintain Libtool? --akim.
- export ac_cv_exeext
- break;;
- * )
- break;;
- esac
-done
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
-See \`config.log' for more details." >&5
-echo "$as_me: error: C compiler cannot create executables
-See \`config.log' for more details." >&2;}
- { (exit 77); exit 77; }; }
-fi
-
-ac_exeext=$ac_cv_exeext
-echo "$as_me:$LINENO: result: $ac_file" >&5
-echo "${ECHO_T}$ac_file" >&6
-
-# Check the compiler produces executables we can run. If not, either
-# the compiler is broken, or we cross compile.
-echo "$as_me:$LINENO: checking whether the C compiler works" >&5
-echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6
-# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
-# If not cross compiling, check that we can run a simple program.
-if test "$cross_compiling" != yes; then
- if { ac_try='./$ac_file'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- cross_compiling=no
- else
- if test "$cross_compiling" = maybe; then
- cross_compiling=yes
- else
- { { echo "$as_me:$LINENO: error: cannot run C compiled programs.
-If you meant to cross compile, use \`--host'.
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot run C compiled programs.
-If you meant to cross compile, use \`--host'.
-See \`config.log' for more details." >&2;}
- { (exit 1); exit 1; }; }
- fi
- fi
-fi
-echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6
-
-rm -f a.out a.exe conftest$ac_cv_exeext b.out
-ac_clean_files=$ac_clean_files_save
-# Check the compiler produces executables we can run. If not, either
-# the compiler is broken, or we cross compile.
-echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
-echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6
-echo "$as_me:$LINENO: result: $cross_compiling" >&5
-echo "${ECHO_T}$cross_compiling" >&6
-
-echo "$as_me:$LINENO: checking for suffix of executables" >&5
-echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; then
- # If both `conftest.exe' and `conftest' are `present' (well, observable)
-# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
-# work properly (i.e., refer to `conftest.exe'), while it won't with
-# `rm'.
-for ac_file in conftest.exe conftest conftest.*; do
- test -f "$ac_file" || continue
- case $ac_file in
- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;
- *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
- export ac_cv_exeext
- break;;
- * ) break;;
- esac
-done
-else
- { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
-See \`config.log' for more details." >&2;}
- { (exit 1); exit 1; }; }
-fi
-
-rm -f conftest$ac_cv_exeext
-echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
-echo "${ECHO_T}$ac_cv_exeext" >&6
-
-rm -f conftest.$ac_ext
-EXEEXT=$ac_cv_exeext
-ac_exeext=$EXEEXT
-echo "$as_me:$LINENO: checking for suffix of object files" >&5
-echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6
-if test "${ac_cv_objext+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.o conftest.obj
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; then
- for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do
- case $ac_file in
- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;;
- *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
- break;;
- esac
-done
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot compute suffix of object files: cannot compile
-See \`config.log' for more details." >&2;}
- { (exit 1); exit 1; }; }
-fi
-
-rm -f conftest.$ac_cv_objext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
-echo "${ECHO_T}$ac_cv_objext" >&6
-OBJEXT=$ac_cv_objext
-ac_objext=$OBJEXT
-echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
-echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6
-if test "${ac_cv_c_compiler_gnu+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-#ifndef __GNUC__
- choke me
-#endif
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_compiler_gnu=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_compiler_gnu=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-ac_cv_c_compiler_gnu=$ac_compiler_gnu
-
-fi
-echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
-echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6
-GCC=`test $ac_compiler_gnu = yes && echo yes`
-ac_test_CFLAGS=${CFLAGS+set}
-ac_save_CFLAGS=$CFLAGS
-CFLAGS="-g"
-echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
-echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6
-if test "${ac_cv_prog_cc_g+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_prog_cc_g=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_prog_cc_g=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
-echo "${ECHO_T}$ac_cv_prog_cc_g" >&6
-if test "$ac_test_CFLAGS" = set; then
- CFLAGS=$ac_save_CFLAGS
-elif test $ac_cv_prog_cc_g = yes; then
- if test "$GCC" = yes; then
- CFLAGS="-g -O2"
- else
- CFLAGS="-g"
- fi
-else
- if test "$GCC" = yes; then
- CFLAGS="-O2"
- else
- CFLAGS=
- fi
-fi
-echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5
-echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6
-if test "${ac_cv_prog_cc_stdc+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_prog_cc_stdc=no
-ac_save_CC=$CC
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <stdarg.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
-struct buf { int x; };
-FILE * (*rcsopen) (struct buf *, struct stat *, int);
-static char *e (p, i)
- char **p;
- int i;
-{
- return p[i];
-}
-static char *f (char * (*g) (char **, int), char **p, ...)
-{
- char *s;
- va_list v;
- va_start (v,p);
- s = g (p, va_arg (v,int));
- va_end (v);
- return s;
-}
-
-/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
- function prototypes and stuff, but not '\xHH' hex character constants.
- These don't provoke an error unfortunately, instead are silently treated
- as 'x'. The following induces an error, until -std1 is added to get
- proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
- array size at least. It's necessary to write '\x00'==0 to get something
- that's true only with -std1. */
-int osf4_cc_array ['\x00' == 0 ? 1 : -1];
-
-int test (int i, double x);
-struct s1 {int (*f) (int a);};
-struct s2 {int (*f) (double a);};
-int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
-int argc;
-char **argv;
-int
-main ()
-{
-return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
- ;
- return 0;
-}
-_ACEOF
-# Don't try gcc -ansi; that turns off useful extensions and
-# breaks some systems' header files.
-# AIX -qlanglvl=ansi
-# Ultrix and OSF/1 -std1
-# HP-UX 10.20 and later -Ae
-# HP-UX older versions -Aa -D_HPUX_SOURCE
-# SVR4 -Xc -D__EXTENSIONS__
-for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
-do
- CC="$ac_save_CC $ac_arg"
- rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_prog_cc_stdc=$ac_arg
-break
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-fi
-rm -f conftest.err conftest.$ac_objext
-done
-rm -f conftest.$ac_ext conftest.$ac_objext
-CC=$ac_save_CC
-
-fi
-
-case "x$ac_cv_prog_cc_stdc" in
- x|xno)
- echo "$as_me:$LINENO: result: none needed" >&5
-echo "${ECHO_T}none needed" >&6 ;;
- *)
- echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
-echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
- CC="$CC $ac_cv_prog_cc_stdc" ;;
-esac
-
-# Some people use a C++ compiler to compile C. Since we use `exit',
-# in C++ we need to declare it. In case someone uses the same compiler
-# for both compiling C and C++ we need to have the C++ compiler decide
-# the declaration of exit, since it's the most demanding environment.
-cat >conftest.$ac_ext <<_ACEOF
-#ifndef __cplusplus
- choke me
-#endif
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- for ac_declaration in \
- '' \
- 'extern "C" void std::exit (int) throw (); using std::exit;' \
- 'extern "C" void std::exit (int); using std::exit;' \
- 'extern "C" void exit (int) throw ();' \
- 'extern "C" void exit (int);' \
- 'void exit (int);'
-do
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_declaration
-#include <stdlib.h>
-int
-main ()
-{
-exit (42);
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- :
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-continue
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_declaration
-int
-main ()
-{
-exit (42);
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- break
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-done
-rm -f conftest*
-if test -n "$ac_declaration"; then
- echo '#ifdef __cplusplus' >>confdefs.h
- echo $ac_declaration >>confdefs.h
- echo '#endif' >>confdefs.h
-fi
-
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-
-for ac_func in posix_memalign
-do
-as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
-echo "$as_me:$LINENO: checking for $ac_func" >&5
-echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
-if eval "test \"\${$as_ac_var+set}\" = set"; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
- For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define $ac_func innocuous_$ac_func
-
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char $ac_func (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef $ac_func
-
-/* Override any gcc2 internal prototype to avoid an error. */
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char $ac_func ();
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
-choke me
-#else
-char (*f) () = $ac_func;
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-int
-main ()
-{
-return f != $ac_func;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- eval "$as_ac_var=yes"
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-eval "$as_ac_var=no"
-fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
-if test `eval echo '${'$as_ac_var'}'` = yes; then
- cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-done
-
# Check whether --enable-kernel or --disable-kernel was given.
@@ -3111,13 +2051,6 @@
s,@LLVM_SRC@,$LLVM_SRC,;t t
s,@LLVM_OBJ@,$LLVM_OBJ,;t t
s,@OMEGA@,$OMEGA,;t t
-s,@CC@,$CC,;t t
-s,@CFLAGS@,$CFLAGS,;t t
-s,@LDFLAGS@,$LDFLAGS,;t t
-s,@CPPFLAGS@,$CPPFLAGS,;t t
-s,@ac_ct_CC@,$ac_ct_CC,;t t
-s,@EXEEXT@,$EXEEXT,;t t
-s,@OBJEXT@,$OBJEXT,;t t
s,@poolallocsrcdir@,$poolallocsrcdir,;t t
s,@poolallocobjdir@,$poolallocobjdir,;t t
s,@LIBOBJS@,$LIBOBJS,;t t
diff --git a/safecode/include/BottomUpCallGraph.h b/safecode/include/BottomUpCallGraph.h
index c6fe913..497888e 100755
--- a/safecode/include/BottomUpCallGraph.h
+++ b/safecode/include/BottomUpCallGraph.h
@@ -1,8 +1,8 @@
#ifndef BOTTOMUP_CALLGRAPH_H
#define BOTTOMUP_CALLGRAPH_H
-#include "dsa/DataStructure.h"
-#include "dsa/DSSupport.h"
#include "llvm/Pass.h"
+#include "llvm/Analysis/DataStructure/DataStructure.h"
+#include "llvm/Analysis/DataStructure/DSSupport.h"
#include "llvm/Function.h"
#include "llvm/Module.h"
diff --git a/safecode/include/InsertPoolChecks.h b/safecode/include/InsertPoolChecks.h
index 4dddf88..a85eed2 100755
--- a/safecode/include/InsertPoolChecks.h
+++ b/safecode/include/InsertPoolChecks.h
@@ -2,121 +2,27 @@
#define INSERT_BOUNDS_H
#include "safecode/Config/config.h"
-#include "ConvertUnsafeAllocas.h"
-#include "llvm/Analysis/ScalarEvolutionExpressions.h"
#include "llvm/Pass.h"
+#include "ConvertUnsafeAllocas.h"
#ifndef LLVA_KERNEL
#include "SafeDynMemAlloc.h"
#include "poolalloc/PoolAllocate.h"
#endif
-#include <map>
-#include <set>
-
-#ifdef LLVA_KERNEL
-#define LLVA_ICONTEXT_SIZE (18*4)
-#define LLVA_INTEGERSTATE_SIZE (18*4)
-#define LLVA_FPSTATE_SIZE (27*4)
-#endif
namespace llvm {
ModulePass *creatInsertPoolChecks();
using namespace CUA;
-struct PreInsertPoolChecks : public ModulePass {
- public:
- virtual bool runOnModule (Module & M);
- virtual void getAnalysisUsage(AnalysisUsage &AU) const {
- // Required passes
- AU.addRequired<ConvertUnsafeAllocas>();
- AU.addRequired<TDDataStructures>();
- AU.addRequired<TargetData>();
-
- // Preserved passes
- AU.addPreserved<ConvertUnsafeAllocas>();
- AU.addPreserved<TDDataStructures>();
- }
-
- bool nodeNeedsAlignment (DSNode * Node) {
- return ((AlignmentNodes.find (Node)) != (AlignmentNodes.end()));
- }
- private:
-#ifndef LLVA_KERNEL
- PoolAllocate * paPass;
- EquivClassGraphs *equivPass;
- EmbeCFreeRemoval *efPass;
-#endif
-
- // Private variables
- CUA::ConvertUnsafeAllocas * cuaPass;
- TDDataStructures * TDPass;
- TargetData * TD;
-
- // Set of DSNodes that require alignment checks
- std::set<DSNode *> AlignmentNodes;
-
- // External functions in the SAFECode run-time library
- Function *PoolCheck;
- Function *PoolCheckArray;
- Function *PoolCheckIArray;
- Function *ExactCheck;
- Function *FunctionCheck;
- Function *FunctionCheckT;
- Function *FunctionCheckG;
- Function *ICCheck;
- Function *BoundsCheck;
- Function *UIBoundsCheck;
- Function *getBounds;
- Function *UIgetBounds;
- Function *ExactCheck2;
- Function *ExactCheck3;
- Function *GetActualValue;
- Function *PoolRegister;
- Function *StackRegister;
- Function *ObjFree;
- Function *StackFree;
- Function *FuncRegister;
- Function *PoolRegMP;
- Function *PoolFindMP;
- Function *getBegin;
- Function *getEnd;
-
- // Private methods
- void addPoolCheckProto(Module &M);
- void registerGlobalArraysWithGlobalPools(Module &M);
- void addLinksNeedingAlignment (DSNode * Node);
-#ifndef LLVA_KERNEL
- Value * getPoolHandle(const Value *V, Function *F, PA::FuncInfo &FI, bool collapsed = false);
-#endif
- Value * createPoolHandle (const Value * V, Function * F);
- Value * createPoolHandle (Module & M, DSNode * Node);
- DSGraph & getDSGraph (Function & F);
- Value* getPD(DSNode* N, Module& M) {
- if (!N) return 0;
- createPoolHandle (M, N);
- if (N->getMP())
- return N->getMP()->getMetaPoolValue();
- else
- return 0;
- }
-};
-
-struct InsertPoolChecks : public FunctionPass {
- public :
+struct InsertPoolChecks : public ModulePass {
+ public :
const char *getPassName() const { return "Inserting pool checks for array bounds "; }
- virtual bool doInitialization (Module &M);
- virtual bool doFinalization (Module &M);
- virtual bool runOnFunction (Function & F);
+ virtual bool runOnModule(Module &M);
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
- AU.addRequired<PreInsertPoolChecks>();
AU.addRequired<ConvertUnsafeAllocas>();
- AU.addRequired<ScalarEvolution>();
- AU.addRequired<LoopInfo>();
-#if 0
- AU.addRequired<CompleteBUDataStructures>();
- AU.addRequired<TDDataStructures>();
-#endif
+// AU.addRequired<CompleteBUDataStructures>();
+// AU.addRequired<TDDataStructures>();
#ifndef LLVA_KERNEL
AU.addRequired<EquivClassGraphs>();
AU.addRequired<PoolAllocate>();
@@ -124,107 +30,38 @@
AU.addRequired<TargetData>();
#else
AU.addRequired<TDDataStructures>();
- AU.addRequired<TargetData>();
#endif
+
};
-
- private :
- // Prerequisite passes
- PreInsertPoolChecks * preSCPass;
- CUA::ConvertUnsafeAllocas * cuaPass;
- ScalarEvolution * scevPass;
- LoopInfo *LI;
- TargetData * TD;
+ private :
+ CUA::ConvertUnsafeAllocas * cuaPass;
#ifndef LLVA_KERNEL
- PoolAllocate * paPass;
- EquivClassGraphs *equivPass;
- EmbeCFreeRemoval *efPass;
+ PoolAllocate * paPass;
+ EquivClassGraphs *equivPass;
+ EmbeCFreeRemoval *efPass;
+ TargetData * TD;
#else
- TDDataStructures * TDPass;
+ TDDataStructures * TDPass;
#endif
-
- // Map of DSNode to Function List Global Variables
- std::map<Value *, GlobalVariable *> FuncListMap;
-
- // Set of DSNodes for which we do full bounds checks
- std::set<DSNode *> PHNeeded;
-
- // Functions
- Function *PoolCheck;
- Function *PoolCheckAlign;
- Function *PoolCheckUI;
- Function *PoolCheckAlignUI;
- Function *PoolCheckArray;
- Function *PoolCheckIArray;
- Function *ExactCheck;
- Function *FunctionCheck;
- Function *FunctionCheckT;
- Function *FunctionCheckG;
- Function *ICCheck;
- Function *BoundsCheck;
- Function *UIBoundsCheck;
- Function *getBounds;
- Function *UIgetBounds;
- Function *ExactCheck2;
- Function *ExactCheck3;
- Function *GetActualValue;
- Function *PoolRegister;
- Function *StackRegister;
- Function *ObjFree;
- Function *StackFree;
- Function *FuncRegister;
- Function *KmemCachegetSize;
- Function *PoolRegMP;
- Function *PoolFindMP;
- Function *getBegin;
- Function *getEnd;
-
- void simplifyGEPList();
- void addObjFrees(Module& M);
- void addMetaPools(Module& M, MetaPool* MP, DSNode* N);
- void addPoolCheckProto(Module &M);
- void addPoolChecks(Module &M);
- void addGetElementPtrChecks(Module &M);
- DSGraph & getDSGraph (Function & F);
- DSNode* getDSNode(const Value *V, Function *F);
- unsigned getDSNodeOffset(const Value *V, Function *F);
- void addLoadStoreChecks (Function & F);
- void insertAlignmentCheck (LoadInst * LI);
- void TransformFunction(Function &F);
- void handleCallInst(CallInst *CI);
- void handleGetElementPtr(GetElementPtrInst *MAI);
- void addGetActualValue(SetCondInst *SCI, unsigned operand);
- void registerAllocaInst(AllocaInst *AI, AllocaInst *AIOrig);
- GlobalVariable * getOrCreateFunctionTable (DSNode * Node, Value * PH, Module * M);
- void addExactCheck (Instruction * GEP, Value * Index, Value * Bound);
- void addExactCheck (Value * Pointer, Value * Index, Value * Bound, Instruction * InsertPt);
- void addExactCheck2 (Value * Base, Value * Result, Value * Bound, Instruction * InsertPt);
- Value * addExactCheck3 (Value * Source, Value * Result, Value * Bound, Instruction * Next);
- bool insertExactCheck (GetElementPtrInst * GEP);
- bool insertExactCheck (Instruction * , Value *, Value *, Instruction *);
- void insertFunctionCheck(CallInst* CI);
- void insertICCheck (Value * Pointer, Instruction * InsertPt);
- Value * insertBoundsCheck (Instruction * , Value *, Value *, Instruction *);
- bool AggregateGEPs (GetElementPtrInst * GEP, std::set<Instruction *> & GEPs);
- bool findCheckedPointer (Value * PointerOperand);
- void addHeapRegs (Module & M);
-
+ Function *PoolCheck;
+ Function *PoolCheckArray;
+ Function *ExactCheck;
+ Function *FunctionCheck;
+ void addPoolCheckProto(Module &M);
+ void addPoolChecks(Module &M);
+ void addGetElementPtrChecks(Module &M);
+ DSNode* getDSNode(const Value *V, Function *F);
+ unsigned getDSNodeOffset(const Value *V, Function *F);
+ void addLoadStoreChecks(Module &M);
#ifndef LLVA_KERNEL
- void addLSChecks(Value *Vnew, const Value *V, Instruction *I, Function *F);
- Value * getPoolHandle(const Value *V, Function *F, PA::FuncInfo &FI, bool collapsed = false);
- Value * getPoolHandle(const Value *V, Function *F, bool collapsed = false);
+ void addLSChecks(Value *Vnew, const Value *V, Instruction *I, Function *F);
+ Value * getPoolHandle(const Value *V, Function *F, PA::FuncInfo &FI, bool collapsed = false);
+ void registerGlobalArraysWithGlobalPools(Module &M);
#else
- Value* getPD(DSNode* N, Module& M) {
- if (!N) return 0;
- addMetaPools(M, N->getMP(), N);
- if (N->getMP())
- return N->getMP()->getMetaPoolValue();
- else
- return 0;
- }
- void addLSChecks(Value *V, Instruction *I, Function *F);
- Value * getPoolHandle(const Value *V, Function *F);
+ void addLSChecks(Value *V, Instruction *I, Function *F);
+ Value * getPoolHandle(const Value *V, Function *F);
#endif
+
};
}
#endif
diff --git a/safecode/include/ProofWrap/ProofWrap.h b/safecode/include/ProofWrap/ProofWrap.h
deleted file mode 100755
index 40b47b1..0000000
--- a/safecode/include/ProofWrap/ProofWrap.h
+++ /dev/null
@@ -1,79 +0,0 @@
-#include <map>
-#include <set>
-#include <iterator>
-#include "llvm/DerivedTypes.h"
-#include "llvm/Module.h"
-#include "llvm/Instructions.h"
-
-using namespace llvm;
-
-namespace {
- struct ProofStrip : public ModulePass {
- const Value* getProof(const Value* V) {
- return stuff[V];
- }
-
- virtual bool runOnModule(Module &M);
-
- private:
- void setProof(const Value* V, const Value* P) {
- stuff[V] = P;
- }
-
- std::map<const Value*, const Value*> stuff;
- };
-
-
-
- // call AddProof until you are done annotating
- // then call Finalize
- struct ProofPlace {
- std::map<Value*, Value*> stuff;
-
- void AddProof(Value* V, Value* P) {
- assert(isa<PointerType>(V->getType()));
- assert(isa<ConstantInt>(P));
- stuff[V] = P;
- }
-
- void AddProof(Value* V, unsigned P) {
- AddProof(V, ConstantInt::get(Type::LongTy,P));
- }
-
- void Finalize(Module& M) {
- //try to be semi clever
- //find homes for values
- BasicBlock* SomeBB;
- std::map<std::pair<BasicBlock*, Value*>, std::set<Value*> > homes;
- for (std::map<Value*, Value*>::iterator ii = stuff.begin(),
- ee = stuff.end(); ii != ee; ++ii) {
- Value* V = ii->first;
- if (isa<GlobalValue>(V)) {
- homes[std::make_pair((BasicBlock*)0, ii->second)].insert(V);
- } else if (isa<Instruction>(V)) {
- homes[std::make_pair(cast<Instruction>(V)->getParent(), ii->second)].insert(V);
- SomeBB = cast<Instruction>(V)->getParent();
- } else {
- V->dump();
- assert(0 && "Not supported");
- }
- }
-
- //get proof function
- std::vector<const Type * > FTV;
- FTV.push_back(Type::LongTy);
- FunctionType* FT = FunctionType::get(Type::VoidTy, FTV, true);
- Function* F = M.getOrInsertFunction("llvm.proof.ptr", FT);
-
- //insert at end of BBs
- for (std::map<std::pair<BasicBlock*, Value*>, std::set<Value*> >::iterator
- ii = homes.begin(), ee = homes.end(); ii != ee; ++ii) {
- BasicBlock* BB = ii->first.first ? ii->first.first : SomeBB;
- std::vector<Value*> Args;
- Args.push_back(ii->first.second);
- std::copy(ii->second.begin(), ii->second.end(), std::back_insert_iterator<std::vector<Value*> > (Args));
- new CallInst(F, Args, "", BB->getTerminator());
- }
- }
- };
-}
diff --git a/safecode/include/SafeDynMemAlloc.h b/safecode/include/SafeDynMemAlloc.h
index 3df7fcf..bd865e0 100755
--- a/safecode/include/SafeDynMemAlloc.h
+++ b/safecode/include/SafeDynMemAlloc.h
@@ -9,8 +9,6 @@
#define LLVM_EMBEC_H
-#include "dsa/DataStructure.h"
-#include "dsa/DSGraph.h"
#include "safecode/Config/config.h"
#include "llvm/Pass.h"
#include "poolalloc/PoolAllocate.h"
@@ -21,6 +19,8 @@
#include "llvm/Support/CFG.h"
#include "llvm/Analysis/CallGraph.h"
#include "llvm/ADT/VectorExtras.h"
+#include "llvm/Analysis/DataStructure/DataStructure.h"
+#include "llvm/Analysis/DataStructure/DSGraph.h"
#include "llvm/Support/Debug.h"
#include <set>
#include <map>
diff --git a/safecode/include/StackSafety.h b/safecode/include/StackSafety.h
index e9469da..56fbe0e 100755
--- a/safecode/include/StackSafety.h
+++ b/safecode/include/StackSafety.h
@@ -7,10 +7,10 @@
#ifndef LLVM_STACKSAFETY_H
#define LLVM_STACKSAFETY_H
-#include "dsa/DataStructure.h"
-#include "dsa/DSGraph.h"
-#include "dsa/DSNode.h"
#include "llvm/Pass.h"
+#include "llvm/Analysis/DataStructure/DataStructure.h"
+#include "llvm/Analysis/DataStructure/DSGraph.h"
+#include "llvm/Analysis/DataStructure/DSNode.h"
#include <set>
namespace llvm {
diff --git a/safecode/include/safecode/Config/config.h.in b/safecode/include/safecode/Config/config.h.in
index 419e798..ffe008e 100755
--- a/safecode/include/safecode/Config/config.h.in
+++ b/safecode/include/safecode/Config/config.h.in
@@ -1,8 +1,5 @@
/* include/llvm/Config/config.h.in. Generated from autoconf/configure.ac by autoheader. */
-/* Define to 1 if you have the 'posix_memalign' function. */
-#undef HAVE_POSIX_MEMALIGN
-
/* Define if dlopen(0) will open the symbols of the program */
#undef CAN_DLOPEN_SELF
diff --git a/safecode/lib/InsertPoolChecks/Makefile b/safecode/lib/InsertPoolChecks/Makefile
index 903a11d..788eac8 100755
--- a/safecode/lib/InsertPoolChecks/Makefile
+++ b/safecode/lib/InsertPoolChecks/Makefile
@@ -2,6 +2,7 @@
LEVEL = ../../
SHARED_LIBRARY=1
+DONT_BUILD_RELINKED=1
LIBRARYNAME=addchecks
include $(LEVEL)/Makefile.common
diff --git a/safecode/lib/InsertPoolChecks/insert.cpp b/safecode/lib/InsertPoolChecks/insert.cpp
index 18418f5..95c0ed1 100755
--- a/safecode/lib/InsertPoolChecks/insert.cpp
+++ b/safecode/lib/InsertPoolChecks/insert.cpp
@@ -1,62 +1,28 @@
-//===-- insert.cpp - Insert SAFECode Run-time Checks ----------------------===//
-//
-// SAFECode
-//
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the insertion of SAFECode's run-time checks.
-//
-//===----------------------------------------------------------------------===//
-
#include "safecode/Config/config.h"
#include "InsertPoolChecks.h"
-#include "SCUtils.h"
#include "llvm/Instruction.h"
#include "llvm/Module.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/InstIterator.h"
+#include <iostream>
#include "llvm/ADT/VectorExtras.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Support/Debug.h"
-#include "llvm/Support/ConstantRange.h"
-#include "llvm/Analysis/ScalarEvolutionExpander.h"
-#include "llvm/Analysis/LoopInfo.h"
-#include <iostream>
-#include <vector>
-#include <set>
using namespace llvm;
-
extern Value *getRepresentativeMetaPD(Value *);
+RegisterPass<InsertPoolChecks> ipc("safecode", "insert runtime checks");
-RegisterPass<PreInsertPoolChecks> pipc ("presafecode", "prepare for SAFECode");
-RegisterPass<InsertPoolChecks> ipc ("safecode", "insert runtime checks");
-
-cl::opt<bool> EnableSplitChecks ("enable-splitchecks", cl::Hidden,
- cl::init(false),
- cl::desc("Split lookup and checks"));
-
-cl::opt<bool> InsertPoolChecksForArrays("boundschecks-usepoolchecks",
- cl::Hidden, cl::init(false),
- cl::desc("Insert pool checks instead of exact bounds checks"));
-
// Options for Enabling/Disabling the Insertion of Various Checks
-cl::opt<bool> EnableUnknownChecks ("enable-unknownchecks", cl::Hidden,
- cl::init(false),
- cl::desc("Enable Checks on Incomplete/Unknown Nodes"));
+cl::opt<bool> EnableIncompleteChecks ("enable-incompletechecks", cl::Hidden,
+ cl::init(false),
+ cl::desc("Enable Checks on Incomplete Nodes"));
cl::opt<bool> EnableNullChecks ("enable-nullchecks", cl::Hidden,
cl::init(false),
cl::desc("Enable Checks on NULL Pools"));
-cl::opt<bool> DisableRegisterGlobals ("disable-regglobals", cl::Hidden,
- cl::init(false),
- cl::desc("Do not register globals"));
-
cl::opt<bool> DisableLSChecks ("disable-lschecks", cl::Hidden,
cl::init(false),
cl::desc("Disable Load/Store Checks"));
@@ -65,22 +31,10 @@
cl::init(false),
cl::desc("Disable GetElementPtr(GEP) Checks"));
-cl::opt<bool> DisableStackChecks ("disable-stackchecks", cl::Hidden,
- cl::init(false),
- cl::desc("Disable Stack Checks"));
-
-cl::opt<bool> DisableFuncChecks ("disable-funcchecks", cl::Hidden,
- cl::init(false),
- cl::desc("Disable Function Call Checks"));
-
cl::opt<bool> DisableIntrinsicChecks ("disable-intrinchecks", cl::Hidden,
cl::init(false),
cl::desc("Disable Intrinsic Checks"));
-cl::opt<bool> EnableMonotonicOptimisation("enable-monotonic", cl::Hidden,
- cl::init(false),
- cl::desc("Enable LICM for bounds checks on monotonic loops"));
-
// Options for where to insert various initialization code
cl::opt<string> InitFunctionName ("initfunc",
cl::desc("Specify name of initialization "
@@ -95,485 +49,49 @@
static Statistic<> MissChecks ("safecode",
"Poolchecks omitted due to bad pool descriptor");
static Statistic<> PoolChecks ("safecode", "Poolchecks Added");
-
-static Statistic<> FuncChecks ("safecode", "Indirect Call Checks Added");
-static Statistic<> MissedFuncChecks ("safecode", "Indirect Call Checks Missed");
-static Statistic<> SavedPoolChecks ("safecode", "Pool Checks Performed on Checked Pointers");
-static Statistic<> AlignChecks ("safecode", "Number of alignment checks required");
-static Statistic<> AlignLSChecks ("safecode", "Number of alignment on load/store checks required");
-
-// Bounds Check Statistics
-static Statistic<> BoundsChecks ("safecode",
- "Total bounds checks inserted");
-static Statistic<> IBoundsChecks ("safecode",
- "Bounds checks with incomplete DSNode");
-static Statistic<> UBoundsChecks ("safecode",
- "Bounds checks with unknown DSNode");
-static Statistic<> ABoundsChecks ("safecode",
- "Bounds checks with stack DSNode");
-static Statistic<> NullBoundsChecks ("safecode",
- "Missed bounds checks - NULL pool handle");
-static Statistic<> NoSHGBoundsChecks ("safecode",
- "Missed bounds checks - no SHG DSNode");
-
+static Statistic<> BoundChecks("safecode",
+ "Bounds checks inserted");
static Statistic<> MissedIncompleteChecks ("safecode",
"Poolchecks missed because of incompleteness");
static Statistic<> MissedMultDimArrayChecks ("safecode",
"Multi-dimensional array checks");
+static Statistic<> MissedStackChecks ("safecode", "Missed stack checks");
static Statistic<> MissedGlobalChecks ("safecode", "Missed global checks");
static Statistic<> MissedNullChecks ("safecode", "Missed PD checks");
-// Exact Check Statistics
-static Statistic<> ExactChecks ("safecode", "Exactchecks inserted");
-static Statistic<> ConstExactChecks ("safecode", "Omitted Exactchecks with constant arguments");
-static Statistic<> ZeroFuncChecks ("safecode", "Indirect Call Checks with Zero Targets");
-
-// Object registration statistics
-static Statistic<> StackRegisters ("safecode", "Stack registrations");
-static Statistic<> SavedRegAllocs ("safecode", "Stack registrations avoided");
+bool InsertPoolChecks::runOnModule(Module &M) {
+ cuaPass = &getAnalysis<ConvertUnsafeAllocas>();
+ // budsPass = &getAnalysis<CompleteBUDataStructures>();
+#ifndef LLVA_KERNEL
+ paPass = &getAnalysis<PoolAllocate>();
+ equivPass = &(paPass->getECGraphs());
+ efPass = &getAnalysis<EmbeCFreeRemoval>();
+ TD = &getAnalysis<TargetData>();
+#else
+ TDPass = &getAnalysis<TDDataStructures>();
+#endif
-// Other statistics
-static Statistic<> StructGEPsRemoved ("safecode", "Structure GEP Checks Removed");
+ //add the new poolcheck prototype
+ addPoolCheckProto(M);
+#ifndef LLVA_KERNEL
+ //register global arrays and collapsed nodes with global pools
+ registerGlobalArraysWithGlobalPools(M);
+#endif
+ //Replace old poolcheck with the new one
+ addPoolChecks(M);
-//MonotonicOpts
-static Statistic<> MonotonicOpts ("safecode", "Number of monotonic LICM bounds check optimisations");
-
-// The set of values that already have run-time checks
-static std::set<Value *> CheckedValues;
-
-////////////////////////////////////////////////////////////////////////////
-// Static Functions
-////////////////////////////////////////////////////////////////////////////
-
-static inline bool
-isNodeRegistered (DSNode * Node) {
- // Do not perform checks on the pointer if its DSNode does not have a known
- // allocation site.
- if (!((Node->isAllocaNode()) ||
- (Node->isHeapNode()) ||
- (Node->isGlobalNode()))) {
- ++NoSHGBoundsChecks;
- return false;
- }
-
+ //
+ // Update the statistics.
+ //
+ PoolChecks = NullChecks + FullChecks;
+
return true;
}
-//Do not replace these with check results
-static std::set<Value*> AddedValues;
-
-static GlobalVariable*
-makeMetaPool(Module* M, DSNode* N) {
- //Here we insert a global meta pool
- //Now create a meta pool for this value, DSN Node
- const Type * VoidPtrType = PointerType::get(Type::SByteTy);
- std::vector<const Type*> MPTV;
- for (int x = 0; x < 9; ++x)
- MPTV.push_back(VoidPtrType);
- // Add the types for the hit cache
- MPTV.push_back(Type::UIntTy);
- MPTV.push_back(ArrayType::get (Type::UIntTy, 4));
- MPTV.push_back(ArrayType::get (Type::UIntTy, 4));
- MPTV.push_back(ArrayType::get (VoidPtrType, 4));
-
- const StructType* MPT = StructType::get(MPTV);
-
- static int x = 0;
- std::string Name = "_metaPool_";
-
- unsigned Flags = N ? N->getMP()->getFlags() : 0;
- if(Flags & DSNode::Incomplete)
- Name += "I";
- if(Flags & DSNode::UnknownNode)
- Name += "U";
- if(Flags & DSNode::AllocaNode)
- Name += "A";
- if(Flags & DSNode::GlobalNode)
- Name += "G";
- if(Flags & DSNode::HeapNode)
- Name += "H";
- if( N && N->isNodeCompletelyFolded())
- Name += "F";
- Name += "_";
- char c[100];
- snprintf(c, sizeof(c), "%d", x);
- Name += c;
- Name += "_";
- ++x;
-
- return new GlobalVariable(
- /*type=*/ MPT,
- /*isConstant=*/ false,
- /*Linkage=*/ GlobalValue::InternalLinkage,
- /*initializer=*/ Constant::getNullValue(MPT),
- /*name=*/ Name,
- /*parent=*/ M );
-}
-
#ifndef LLVA_KERNEL
-Value *
-PreInsertPoolChecks::getPoolHandle(const Value *V, Function *F, PA::FuncInfo &FI, bool collapsed) {
- DSGraph &TDG = getDSGraph(*F);
- const DSNode *Node = TDG.getNodeForValue((Value *)V).getNode();
- // Get the pool handle for this DSNode...
- // assert(!Node->isUnknownNode() && "Unknown node \n");
- Type *VoidPtrType = PointerType::get(Type::SByteTy);
- Type *PoolDescType = ArrayType::get(VoidPtrType, 50);
- Type *PoolDescPtrTy = PointerType::get(PoolDescType);
- if (!Node) {
- return 0; //0 means there is no isse with the value, otherwise there will be a callnode
- }
- if (Node->isUnknownNode()) {
- //FIXME this should be in a top down pass or propagated like collapsed pools below
- if (!collapsed) {
- unsigned offset = TDG.getNodeForValue((Value *)V).getOffset();
- assert((!offset) && " we don't handle middle of structs yet\n");
- return Constant::getNullValue(PoolDescPtrTy);
- }
- }
- std::map<const DSNode*, Value*>::iterator I = FI.PoolDescriptors.find(Node);
- map <Function *, set<Value *> > &
- CollapsedPoolPtrs = efPass->CollapsedPoolPtrs;
-
- if (I != FI.PoolDescriptors.end()) {
- // Check that the node pointed to by V in the TD DS graph is not
- // collapsed
-
- if (!collapsed && CollapsedPoolPtrs.count(F)) {
- Value *v = I->second;
- if (CollapsedPoolPtrs[F].find(I->second) != CollapsedPoolPtrs[F].end()) {
-#ifdef DEBUG
- std::cerr << "Collapsed pools \n";
-#endif
- return Constant::getNullValue(PoolDescPtrTy);
- } else {
- return v;
- }
- } else {
- return I->second;
- }
- }
- return 0;
-}
-#endif
-
-Value *
-PreInsertPoolChecks::createPoolHandle (Module & M, DSNode * Node) {
- // If there is no node, return NULL.
- if (!Node) return 0;
-
- // Get the DSNode's MetaPool. If it doesn't have one, return NULL.
- MetaPool * MP = Node->getMP();
- if (!MP) return 0;
-
- // If the MetaPool global variable has already been created, then simply
- // return it. Otherwise, create one.
- if (!(MP->getMetaPoolValue()))
- MP->setMetaPoolValue (makeMetaPool (&M, Node));
- return (MP->getMetaPoolValue());
-}
-
-
-Value *
-PreInsertPoolChecks::createPoolHandle (const Value * V, Function * F) {
- //
- // Get the DSNode from the Top Down DSGraph.
- //
- DSGraph &TDG = getDSGraph(*F);
- DSNode *Node = TDG.getNodeForValue((Value *)V).getNode();
-
- // If there is no node, return NULL.
- if (!Node) return 0;
-
- // Get the DSNode's MetaPool. If it doesn't have one, return NULL.
- MetaPool * MP = Node->getMP();
- if (!MP) return 0;
-
- // If the MetaPool global variable has already been created, then simply
- // return it. Otherwise, create one.
- if (!(MP->getMetaPoolValue()))
- MP->setMetaPoolValue (makeMetaPool (F->getParent(), Node));
- return (MP->getMetaPoolValue());
-}
-
-static void
-AddCallToRegFunc (Function* F, GlobalVariable* GV, Function* PR, Value* PH,
- Value* AllocSize) {
- //
- // First, make sure that we're not registering an external zero-sized global.
- // These are caused by the following C construct and should never be checked:
- // extern variable[];
- //
- ConstantInt * C;
- if (GV->isExternal())
- if ((C = dyn_cast<ConstantInt>(AllocSize)) && (!(C->getZExtValue())))
- return;
-
- const Type *VoidPtrType = PointerType::get(Type::SByteTy);
-
- assert(PH && "No PoolHandle for Global!");
-
- BasicBlock::iterator InsertPt = F->getEntryBlock().begin();
- Instruction *GVCasted = new CastInst(GV, VoidPtrType, GV->getName()+"casted",InsertPt);
- Value *PHCasted = new CastInst(PH, VoidPtrType, PH->getName()+"casted",InsertPt);
- AllocSize = castTo (AllocSize, Type::UIntTy, InsertPt);
- std::vector<Value *> args (1, PHCasted);
- args.push_back (GVCasted);
- args.push_back (AllocSize);
- new CallInst(PR, args, "", InsertPt);
-}
-
-////////////////////////////////////////////////////////////////////////////
-// Class: PreInsertPoolChecks
-////////////////////////////////////////////////////////////////////////////
-
-//
-// Method: runOnModule()
-//
-// Description:
-// This method is called by the pass manager. The job of this class is to
-// create any global variables and inter-procedural changes that cannot be
-// done in the doInitialization() method of the InsertPoolChecks class.
-//
-bool
-PreInsertPoolChecks::runOnModule (Module & M) {
- // Retrieve the analysis results from other passes
- cuaPass = &getAnalysis<ConvertUnsafeAllocas>();
- TDPass = &getAnalysis<TDDataStructures>();
- TD = &getAnalysis<TargetData>();
-
- // Add prototypes for the run-time checks to the module
- addPoolCheckProto (M);
-
- // Register global arrays and collapsed nodes with global pools
- if (!DisableRegisterGlobals) registerGlobalArraysWithGlobalPools(M);
-
- //
- // Create a MetaPool global variable for every DSNode that we might
- // encounter.
- //
- Module::iterator mI = M.begin(), mE = M.end();
- for ( ; mI != mE; ++mI) {
- Function *F = mI;
-
- // Skip functions that are external
- if (F->isExternal()) continue;
-
- // Skip the poolcheckglobals() function because it won't have a DSGraph
- if (F->getName() == "poolcheckglobals") continue;
-
- // Create a MetaPool variable for each DSNode in the DSGraph.
- DSGraph & TDG = getDSGraph(*F);
- DSGraph::node_iterator NI = TDG.node_begin(), NE = TDG.node_end();
- while (NI != NE) {
- addLinksNeedingAlignment (NI);
- createPoolHandle (M, NI);
- ++NI;
- }
- }
-}
-
-//
-// Method: getDSGraph()
-//
-// Description:
-// Return the DSGraph for the given function. This method automatically
-// selects the correct pass to query for the graph based upon whether we're
-// doing user-space or kernel analysis.
-//
-DSGraph &
-PreInsertPoolChecks::getDSGraph(Function & F) {
-#ifndef LLVA_KERNEL
- return equivPass->getDSGraph(F);
-#else
- return TDPass->getDSGraph(F);
-#endif
-}
-
-//
-// Method: addLinksNeedingAlignment()
-//
-// Description:
-// Determine if this DSNode has any pointers to DSNodes which will require
-// alignment checks. If so, add those DSNodes to the set of DSNodes needing
-// alignment checks. Note that we do not determine if the *given* node needs
-// alignment checks.
-//
-void
-PreInsertPoolChecks::addLinksNeedingAlignment (DSNode * Node) {
- //
- // Determine whether an alignment check is needed. This occurs when a DSNode
- // is type unknown (collapsed) but has pointers to type known (uncollapsed)
- // DSNodes.
- //
- if ((Node) && (Node->isNodeCompletelyFolded())) {
- for (unsigned i = 0 ; i < Node->getNumLinks(); ++i) {
- DSNode * LinkNode = Node->getLink(i).getNode();
- if (LinkNode && (!(LinkNode->isNodeCompletelyFolded()))) {
- AlignmentNodes.insert (LinkNode);
- }
- }
- }
-}
-
-void
-PreInsertPoolChecks::addPoolCheckProto(Module &M) {
- const Type * VoidPtrType = PointerType::get(Type::SByteTy);
-#if 0
- const Type *PoolDescType = ArrayType::get(VoidPtrType, 50);
- // StructType::get(make_vector<const Type*>(VoidPtrType, VoidPtrType,
- // Type::UIntTy, Type::UIntTy, 0));
- const Type * PoolDescTypePtr = PointerType::get(PoolDescType);
-#endif
-
- std::vector<const Type *> Arg(1, VoidPtrType);
- Arg.push_back(VoidPtrType);
- FunctionType *PoolCheckTy =
- FunctionType::get(Type::VoidTy,Arg, false);
- PoolCheck = M.getOrInsertFunction("poolcheck", PoolCheckTy);
-
- std::vector<const Type *> Arg2(1, VoidPtrType);
- Arg2.push_back(VoidPtrType);
- Arg2.push_back(VoidPtrType);
- FunctionType *PoolCheckArrayTy =
- FunctionType::get(Type::VoidTy,Arg2, false);
- PoolCheckArray = M.getOrInsertFunction("poolcheckarray", PoolCheckArrayTy);
- PoolCheckIArray = M.getOrInsertFunction("poolcheckarray_i", PoolCheckArrayTy);
-
-
- std::vector<const Type *> Arg3(1, VoidPtrType);
- Arg3.push_back(VoidPtrType); //for output
- Arg3.push_back(VoidPtrType); //for referent
- FunctionType *BoundsCheckTy = FunctionType::get(VoidPtrType,Arg3, false);
- BoundsCheck = M.getOrInsertFunction("pchk_bounds", BoundsCheckTy);
- UIBoundsCheck = M.getOrInsertFunction("pchk_bounds_i", BoundsCheckTy);
-
- std::vector<const Type *> Arg4(1, VoidPtrType);
- Arg4.push_back(VoidPtrType);
- FunctionType *getBoundsTy = FunctionType::get(VoidPtrType,Arg4, false);
- getBounds = M.getOrInsertFunction("getBounds", getBoundsTy);
- UIgetBounds = M.getOrInsertFunction("getBounds_i", getBoundsTy);
-
- //Get the poolregister function
- PoolRegister = M.getOrInsertFunction("pchk_reg_obj", Type::VoidTy, VoidPtrType,
- VoidPtrType, Type::UIntTy, NULL);
- StackRegister = M.getOrInsertFunction("pchk_reg_stack", Type::VoidTy, VoidPtrType,
- VoidPtrType, Type::UIntTy, NULL);
- ObjFree = M.getOrInsertFunction("pchk_drop_obj", Type::VoidTy, VoidPtrType,
- VoidPtrType, NULL);
- StackFree = M.getOrInsertFunction("pchk_drop_stack", Type::VoidTy, VoidPtrType,
- VoidPtrType, NULL);
-
- FuncRegister = M.getOrInsertFunction("pchk_reg_func", Type::VoidTy, VoidPtrType, Type::UIntTy, PointerType::get(VoidPtrType), NULL);
-
- PoolFindMP = M.getOrInsertFunction("pchk_getLoc", VoidPtrType, VoidPtrType, NULL);
- PoolRegMP = M.getOrInsertFunction("pchk_reg_pool", Type::VoidTy, VoidPtrType, VoidPtrType, VoidPtrType, NULL);
-
- std::vector<const Type *> FArg2(1, Type::IntTy);
- FArg2.push_back(Type::IntTy);
- FArg2.push_back(VoidPtrType);
- FunctionType *ExactCheckTy = FunctionType::get(VoidPtrType, FArg2, false);
- ExactCheck = M.getOrInsertFunction("exactcheck", ExactCheckTy);
-
- std::vector<const Type *> FArg3(1, Type::UIntTy);
- FArg3.push_back(VoidPtrType);
- FArg3.push_back(VoidPtrType);
- FArg3.push_back(VoidPtrType);
- FArg3.push_back(VoidPtrType);
- FArg3.push_back(VoidPtrType);
- FArg3.push_back(VoidPtrType);
- FArg3.push_back(VoidPtrType);
- FunctionType *FunctionCheckTy = FunctionType::get(Type::VoidTy, FArg3, true);
- FunctionCheck = M.getOrInsertFunction("funccheck", FunctionCheckTy);
-
- std::vector<const Type *> FArg6(1, VoidPtrType);
- FArg6.push_back(VoidPtrType);
- FunctionType *FunctionCheckGTy = FunctionType::get(Type::VoidTy, FArg6, true);
- FunctionCheckG = M.getOrInsertFunction("funccheck_g", FunctionCheckGTy);
-
- std::vector<const Type *> FArg9(1, Type::UIntTy);
- FArg9.push_back(VoidPtrType);
- FArg9.push_back(PointerType::get(VoidPtrType));
- FunctionType *FunctionCheckTTy = FunctionType::get(Type::VoidTy, FArg9, true);
- FunctionCheckT = M.getOrInsertFunction("funccheck_t", FunctionCheckTTy);
-
- FArg9.clear();
- FArg9.push_back(VoidPtrType);
- FunctionType *ICCheckTy = FunctionType::get(Type::VoidTy, FArg9, true);
- ICCheck = M.getOrInsertFunction("pchk_iccheck", ICCheckTy);
-
- std::vector<const Type*> FArg5(1, VoidPtrType);
- FArg5.push_back(VoidPtrType);
- FunctionType *GetActualValueTy = FunctionType::get(VoidPtrType, FArg5, false);
- GetActualValue = M.getOrInsertFunction("pchk_getActualValue", GetActualValueTy);
-
- std::vector<const Type*> FArg4(1, VoidPtrType); //base
- FArg4.push_back(VoidPtrType); //result
- FArg4.push_back(Type::UIntTy); //size
- FunctionType *ExactCheck2Ty = FunctionType::get(VoidPtrType, FArg4, false);
- ExactCheck2 = M.getOrInsertFunction("exactcheck2", ExactCheck2Ty);
-
- std::vector<const Type*> FArg7(1, VoidPtrType); //base
- FArg7.push_back(VoidPtrType); //result
- FArg7.push_back(VoidPtrType); //end
- FunctionType *ExactCheck3Ty = FunctionType::get(VoidPtrType, FArg7, false);
- ExactCheck3 = M.getOrInsertFunction("exactcheck3", ExactCheck3Ty);
-
- std::vector<const Type*> FArg8(1, VoidPtrType); //base
- FunctionType *getBeginEndTy = FunctionType::get(VoidPtrType, FArg8, false);
- getBegin = M.getOrInsertFunction("getBegin", getBeginEndTy);
- getEnd = M.getOrInsertFunction("getEnd", getBeginEndTy);
-}
-
-void
-PreInsertPoolChecks::registerGlobalArraysWithGlobalPools(Module &M) {
-#ifdef LLVA_KERNEL
-
- const Type *VoidPtrType = PointerType::get(Type::SByteTy);
- const Type *PoolDescType = ArrayType::get(VoidPtrType, 50);
- const Type *PoolDescPtrTy = PointerType::get(PoolDescType);
- const Type* csiType = Type::getPrimitiveType(Type::UIntTyID);
-
- //Get the registration function
- std::vector<const Type*> Vt;
- const FunctionType* RFT = FunctionType::get(Type::VoidTy, Vt, false);
- Function* RegFunc = M.getOrInsertFunction("poolcheckglobals", RFT);
- if (RegFunc->empty()) {
- BasicBlock* BB = new BasicBlock("reg", RegFunc);
- new ReturnInst(BB);
- }
-
- //Now iterate over globals and register all the arrays
- DSGraph &G = TDPass->getGlobalsGraph();
- Module::global_iterator GI = M.global_begin(), GE = M.global_end();
- for ( ; GI != GE; ++GI) {
- if (GlobalVariable *GV = dyn_cast<GlobalVariable>(GI)) {
- if (GV->getType() != PoolDescPtrTy) {
- GlobalValue * GVLeader = G.getScalarMap().getLeaderForGlobal(GV);
- DSNode *DSN = G.getNodeForValue(GVLeader).getNode();
- if (((isa<ArrayType>(GV->getType()->getElementType())) ||
- (DSN && DSN->isNodeCompletelyFolded()))
- && !isa<OpaqueType>(GV->getType())
- && !(isa<PointerType>(GV->getType()) &&
- isa<OpaqueType>(cast<PointerType>(GV->getType())->getElementType()))) {
- Value * AllocSize;
- if (const ArrayType *AT = dyn_cast<ArrayType>(GV->getType()->getElementType())) {
- //std::cerr << "found global" << *GI << std::endl;
- AllocSize = ConstantInt::get(csiType,
- (AT->getNumElements() * TD->getTypeSize(AT->getElementType())));
- } else {
- AllocSize = ConstantInt::get(csiType, TD->getTypeSize(GV->getType()->getElementType()));
- }
- Value* PH = getPD(DSN, M);
- if (PH)
- AddCallToRegFunc(RegFunc, GV, PoolRegister, PH, AllocSize);
- }
- }
- }
- }
-#else
+void InsertPoolChecks::registerGlobalArraysWithGlobalPools(Module &M) {
Function *MainFunc = M.getMainFunction();
if (MainFunc == 0 || MainFunc->isExternal()) {
std::cerr << "Cannot do array bounds check for this program"
@@ -611,2764 +129,56 @@
}
}
-
//Now iterate over globals and register all the arrays
- Module::global_iterator GI = M.global_begin(), GE = M.global_end();
- for ( ; GI != GE; ++GI) {
- if (GlobalVariable *GV = dyn_cast<GlobalVariable>(GI)) {
- Type *VoidPtrType = PointerType::get(Type::SByteTy);
- Type *PoolDescType = ArrayType::get(VoidPtrType, 50);
- Type *PoolDescPtrTy = PointerType::get(PoolDescType);
- if (GV->getType() != PoolDescPtrTy) {
- DSGraph &G = equivPass->getGlobalsGraph();
- DSNode *DSN = G.getNodeForValue(GV).getNode();
- if ((isa<ArrayType>(GV->getType()->getElementType())) ||
- DSN->isNodeCompletelyFolded()) {
- Value * AllocSize;
- const Type* csiType = Type::getPrimitiveType(Type::UIntTyID);
- if (const ArrayType *AT = dyn_cast<ArrayType>(GV->getType()->getElementType())) {
- //std::cerr << "found global" << *GI << std::endl;
- AllocSize = ConstantInt::get(csiType,
- (AT->getNumElements() * TD->getTypeSize(AT->getElementType())));
- } else {
- AllocSize = ConstantInt::get(csiType, TD->getTypeSize(GV->getType()));
- }
- Function *PoolRegister = paPass->PoolRegister;
- BasicBlock::iterator InsertPt = MainFunc->getEntryBlock().begin();
- //skip the calls to poolinit
- while ((isa<CallInst>(InsertPt)) ||
- isa<CastInst>(InsertPt) ||
- isa<AllocaInst>(InsertPt) ||
- isa<BinaryOperator>(InsertPt)) ++InsertPt;
-
- std::map<const DSNode *, Value *>::iterator I = paPass->GlobalNodes.find(DSN);
- if (I != paPass->GlobalNodes.end()) {
- Value *PH = I->second;
- Instruction *GVCasted = new CastInst(GV,
- VoidPtrType, GV->getName()+"casted",InsertPt);
- new CallInst(PoolRegister,
- make_vector(PH, AllocSize, GVCasted, 0),
- "", InsertPt);
- } else {
- std::cerr << "pool descriptor not present \n ";
- abort();
- }
- }
- }
- }
- }
-#endif
-}
-
-////////////////////////////////////////////////////////////////////////////
-// Class: InsertPoolChecks
-////////////////////////////////////////////////////////////////////////////
-
-void
-InsertPoolChecks::addPoolCheckProto(Module &M) {
- const Type * VoidPtrType = PointerType::get(Type::SByteTy);
-#if 0
- const Type *PoolDescType = ArrayType::get(VoidPtrType, 50);
- // StructType::get(make_vector<const Type*>(VoidPtrType, VoidPtrType,
- // Type::UIntTy, Type::UIntTy, 0));
- const Type * PoolDescTypePtr = PointerType::get(PoolDescType);
-#endif
-
- std::vector<const Type *> Arg(1, VoidPtrType);
- Arg.push_back(VoidPtrType);
- FunctionType *PoolCheckTy =
- FunctionType::get(Type::VoidTy,Arg, false);
- PoolCheck = M.getOrInsertFunction("poolcheck", PoolCheckTy);
- PoolCheckUI = M.getOrInsertFunction("poolcheck_i", PoolCheckTy);
-
- Arg.clear();
- Arg.push_back(VoidPtrType);
- Arg.push_back(VoidPtrType);
- Arg.push_back(Type::UIntTy);
- PoolCheckTy = FunctionType::get(Type::VoidTy,Arg, false);
- PoolCheckAlign = M.getOrInsertFunction("poolcheckalign", PoolCheckTy);
- PoolCheckAlignUI = M.getOrInsertFunction("poolcheckalign_i", PoolCheckTy);
-
- std::vector<const Type *> Arg2(1, VoidPtrType);
- Arg2.push_back(VoidPtrType);
- Arg2.push_back(VoidPtrType);
- FunctionType *PoolCheckArrayTy =
- FunctionType::get(Type::VoidTy,Arg2, false);
- PoolCheckArray = M.getOrInsertFunction("poolcheckarray", PoolCheckArrayTy);
- PoolCheckIArray = M.getOrInsertFunction("poolcheckarray_i", PoolCheckArrayTy);
-
-
- std::vector<const Type *> Arg3(1, VoidPtrType);
- Arg3.push_back(VoidPtrType); //for output
- Arg3.push_back(VoidPtrType); //for referent
- FunctionType *BoundsCheckTy = FunctionType::get(VoidPtrType,Arg3, false);
- BoundsCheck = M.getOrInsertFunction("pchk_bounds", BoundsCheckTy);
- UIBoundsCheck = M.getOrInsertFunction("pchk_bounds_i", BoundsCheckTy);
-
- std::vector<const Type *> Arg4(1, VoidPtrType);
- Arg4.push_back(VoidPtrType);
- FunctionType *getBoundsTy = FunctionType::get(VoidPtrType,Arg4, false);
- getBounds = M.getOrInsertFunction("getBounds", getBoundsTy);
- UIgetBounds = M.getOrInsertFunction("getBounds_i", getBoundsTy);
-
- //Get the poolregister function
- PoolRegister = M.getOrInsertFunction("pchk_reg_obj", Type::VoidTy, VoidPtrType,
- VoidPtrType, Type::UIntTy, NULL);
- StackRegister = M.getOrInsertFunction("pchk_reg_stack", Type::VoidTy, VoidPtrType,
- VoidPtrType, Type::UIntTy, NULL);
- ObjFree = M.getOrInsertFunction("pchk_drop_obj", Type::VoidTy, VoidPtrType,
- VoidPtrType, NULL);
- StackFree = M.getOrInsertFunction("pchk_drop_stack", Type::VoidTy, VoidPtrType,
- VoidPtrType, NULL);
-
- FuncRegister = M.getOrInsertFunction("pchk_reg_func", Type::VoidTy, VoidPtrType, Type::UIntTy, PointerType::get(VoidPtrType), NULL);
-
- PoolFindMP = M.getOrInsertFunction("pchk_getLoc", VoidPtrType, VoidPtrType, NULL);
- PoolRegMP = M.getOrInsertFunction("pchk_reg_pool", Type::VoidTy, VoidPtrType, VoidPtrType, VoidPtrType, NULL);
-
- // Function *KmemCacheAlloc = M.getNamedFunction("kmem_cache_alloc");
- // assert(KmemCacheAlloc->arg_size() == 2 &&"Kmem_cache_alloc number of arguments != 2");
- // Function::arg_iterator kcai = KmemCacheAlloc->arg_begin();
- // Type *kmem_cache_t = kcai->getType();
- // kcai++;
- // Type *kem_cache_size_t = kcai->getType();
- // We'll use Void * instead of the above
- KmemCachegetSize = M.getOrInsertFunction("kmem_cache_size", Type::UIntTy, VoidPtrType, NULL);
-
- std::vector<const Type *> FArg2(1, Type::IntTy);
- FArg2.push_back(Type::IntTy);
- FArg2.push_back(VoidPtrType);
- FunctionType *ExactCheckTy = FunctionType::get(VoidPtrType, FArg2, false);
- ExactCheck = M.getOrInsertFunction("exactcheck", ExactCheckTy);
-
- std::vector<const Type *> FArg3(1, Type::UIntTy);
- FArg3.push_back(VoidPtrType);
- FArg3.push_back(VoidPtrType);
- FunctionType *FunctionCheckTy = FunctionType::get(Type::VoidTy, FArg3, true);
- FunctionCheck = M.getOrInsertFunction("funccheck", FunctionCheckTy);
-
- std::vector<const Type *> FArg6(1, VoidPtrType);
- FArg6.push_back(VoidPtrType);
- FunctionType *FunctionCheckGTy = FunctionType::get(Type::VoidTy, FArg6, true);
- FunctionCheckG = M.getOrInsertFunction("funccheck_g", FunctionCheckGTy);
-
- std::vector<const Type *> FArg9(1, Type::UIntTy);
- FArg9.push_back(VoidPtrType);
- FArg9.push_back(PointerType::get(VoidPtrType));
- FunctionType *FunctionCheckTTy = FunctionType::get(Type::VoidTy, FArg9, true);
- FunctionCheckT = M.getOrInsertFunction("funccheck_t", FunctionCheckTTy);
-
- FArg9.clear();
- FArg9.push_back(VoidPtrType);
- FunctionType *ICCheckTy = FunctionType::get(Type::VoidTy, FArg9, true);
- ICCheck = M.getOrInsertFunction("pchk_iccheck", ICCheckTy);
-
- std::vector<const Type*> FArg5(1, VoidPtrType);
- FArg5.push_back(VoidPtrType);
- FunctionType *GetActualValueTy = FunctionType::get(VoidPtrType, FArg5, false);
- GetActualValue = M.getOrInsertFunction("pchk_getActualValue", GetActualValueTy);
-
- std::vector<const Type*> FArg4(1, VoidPtrType); //base
- FArg4.push_back(VoidPtrType); //result
- FArg4.push_back(Type::UIntTy); //size
- FunctionType *ExactCheck2Ty = FunctionType::get(VoidPtrType, FArg4, false);
- ExactCheck2 = M.getOrInsertFunction("exactcheck2", ExactCheck2Ty);
-
- std::vector<const Type*> FArg7(1, VoidPtrType); //base
- FArg7.push_back(VoidPtrType); //result
- FArg7.push_back(VoidPtrType); //end
- FunctionType *ExactCheck3Ty = FunctionType::get(VoidPtrType, FArg7, false);
- ExactCheck3 = M.getOrInsertFunction("exactcheck3", ExactCheck3Ty);
-
- std::vector<const Type*> FArg8(1, VoidPtrType); //base
- FunctionType *getBeginEndTy = FunctionType::get(VoidPtrType, FArg8, false);
- getBegin = M.getOrInsertFunction("getBegin", getBeginEndTy);
- getEnd = M.getOrInsertFunction("getEnd", getBeginEndTy);
-}
-
-
-void
-InsertPoolChecks::addHeapRegs (Module & M) {
- DSNode * Node;
- MetaPool * MP;
- const Type * VoidPtrType = PointerType::get(Type::SByteTy);
- std::set<Value *> ProcessedMetaPools;
- std::vector<Value *> args;
-
- while (PHNeeded.size()) {
- Node = *(PHNeeded.begin());
- PHNeeded.erase(Node);
- MP = Node->getMP();
- Value* MPV = MP->getMetaPoolValue();
-
- //
- // Determine if we have already processed this MetaPool. If we have, then
- // just go on to the next DSNode.
- if (ProcessedMetaPools.find (MPV) == ProcessedMetaPools.end())
- ProcessedMetaPools.insert (MPV);
- else
- continue;
-
- // Add registers in front of every allocation
- for (std::list<CallSite>::iterator i = MP->allocs.begin(),
- e = MP->allocs.end(); i != e; ++i) {
- args.clear();
- std::string name = i->getCalledFunction()->getName();
- if (name == "kmem_cache_alloc") {
- Instruction * InsertPt = i->getInstruction();
- //insert a register before
- Value* VP = castTo (i->getArgument(0), VoidPtrType, InsertPt);
- Value* VMP = castTo (MPV, VoidPtrType, InsertPt);
- Value* VMPP = new CallInst(PoolFindMP, VP, "", InsertPt);
-
- args.push_back (VMP);
- args.push_back (VP);
- args.push_back (VMPP);
- new CallInst (PoolRegMP, args, "", i->getInstruction());
-
- //Insert Obj reg using kmem_cache_size after
- Instruction* IP = i->getInstruction()->getNext();
- Value* VRP = castTo (i->getInstruction(), VoidPtrType, IP);
- CallInst *len = new CallInst(KmemCachegetSize, VP, "", IP);
-
- args.clear();
- args.push_back (VMP); //MetaPool
- args.push_back (VRP); //object
- args.push_back (len); //len
- new CallInst(PoolRegister, args, "", IP);
-
-#if 0
- } else if ((name == "kmalloc") ||
-#else
- } else if (
-#endif
- (name == "__vmalloc") ||
- (name == "__alloc_bootmem")) {
- //inser obj register after
- Instruction* IP = i->getInstruction()->getNext();
- Value* VP = castTo (i->getInstruction(), VoidPtrType, IP);
- Value* VMP = castTo (MPV, VoidPtrType, IP);
- Value* len = castTo (i->getArgument(0), Type::UIntTy, IP);
-
- args.push_back (VMP);
- args.push_back (VP);
- args.push_back (len);
- new CallInst(PoolRegister, args, "", IP);
- } else
- assert(0 && "unknown alloc");
- }
- }
-}
-
-void InsertPoolChecks::addMetaPools(Module& M, MetaPool* MP, DSNode* N) {
- if (!MP || MP->getMetaPoolValue()) return;
- MP->setMetaPoolValue(makeMetaPool(&M, N));
- Value* MPV = MP->getMetaPoolValue();
- //added registers in front of every allocation
- for(std::list<CallSite>::iterator i = MP->allocs.begin(),
- e = MP->allocs.end(); i != e; ++i) {
- std::string name = i->getCalledFunction()->getName();
- if (name == "kmem_cache_alloc") {
- //insert a register before
- Value* VP = new CastInst(i->getArgument(0), PointerType::get(Type::SByteTy), "", i->getInstruction());
- Value* VMP = new CastInst(MPV, PointerType::get(Type::SByteTy), "MP", i->getInstruction());
- Value* VMPP = new CallInst(PoolFindMP, make_vector(VP, 0), "", i->getInstruction());
- new CallInst(PoolRegMP, make_vector(VMP, VP, VMPP, 0), "", i->getInstruction());
-#if 0
- } else if ((name == "kmalloc") ||
-#else
- } else if (
-#endif
- (name == "__vmalloc") ||
- (name == "__alloc_bootmem")) {
- //inser obj register after
- Instruction* IP = i->getInstruction()->getNext();
- Value* VP = new CastInst(i->getInstruction(), PointerType::get(Type::SByteTy), "", IP);
- Value* VMP = new CastInst(MPV, PointerType::get(Type::SByteTy), "MP", IP);
- Value* len = new CastInst(i->getArgument(0), Type::UIntTy, "len", IP);
- new CallInst(PoolRegister, make_vector(VMP, VP, len, 0), "", IP);
- } else
- assert(0 && "unknown alloc");
- }
-}
-
-void InsertPoolChecks::addObjFrees(Module& M) {
-#ifdef LLVA_KERNEL
-#if 0
- Function* KMF = M.getNamedFunction("kfree");
-#endif
- Function* VMF = M.getNamedFunction("vfree");
- std::list<Function*> L;
-#if 0
- if (KMF) L.push_back(KMF);
-#endif
- if (VMF) L.push_back(VMF);
- for (std::list<Function*>::iterator ii = L.begin(), ee = L.end();
- ii != ee; ++ii) {
- Function* F = *ii;
- for (Value::use_iterator ii = F->use_begin(), ee = F->use_end();
- ii != ee; ++ii) {
- if (CallInst* CI = dyn_cast<CallInst>(*ii)) {
- if (CI->getCalledFunction() == F) {
- Value* Ptr = CI->getOperand(1);
- Value* MP = getPD(getDSNode(Ptr, CI->getParent()->getParent()), M);
- if (MP) {
- MP = new CastInst(MP, PointerType::get(Type::SByteTy), "MP", CI);
- Ptr = new CastInst(Ptr, PointerType::get(Type::SByteTy), "ADDR", CI);
- new CallInst(ObjFree, make_vector(MP, Ptr, 0), "", CI);
- }
- }
- }
- }
- }
-#endif
-}
-
-//
-// Method: insertICCheck()
-//
-// Description:
-// Perform a run-time check to ensure that this pointer points to the
-// beginning of an interrupt context.
-//
-void
-InsertPoolChecks::insertICCheck (Value * IC, Instruction * InsertPt) {
- const Type * VoidPtrType = PointerType::get(Type::SByteTy);
- Value * CastPointer = castTo (IC, VoidPtrType, InsertPt);
- new CallInst (ICCheck, CastPointer, "", InsertPt);
-}
-
-//
-// Return value:
-// Returns the inserted boundscheck call instruction. This can be used to
-// replace the destination instruction if desired.
-// If no instruction was inserted, it returns Dest.
-//
-Value *
-InsertPoolChecks::insertBoundsCheck (Instruction * I,
- Value * Src,
- Value * Dest,
- Instruction * InsertPt) {
- // Enclosing function
- Function * F = I->getParent()->getParent();
- Function *Fnew = F;
-
- // Source node on which we will look up the pool handle
- Value *newSrc = Src;
-
-#ifndef LLVA_KERNEL
-#ifdef NOEQUIV
- // Some times the ECGraphs doesnt contain F for newly created cloned
- // functions
- if (!equivPass->ContainsDSGraphFor(*F)) {
- PA::FuncInfo *FI = paPass->getFuncInfoOrClone(*F);
- newSrc = FI->MapValueToOriginal(Src);
- Instruction * Inew = FI->MapValueToOriginal(I);
- assert(newSrc && " Instruction not in value map (clone)\n");
- }
- Fnew = Inew->getParent()->getParent();
-#endif
-#endif
-
- //
- // Get the pool handle for the source pointer.
- //
- Value *PH = getPoolHandle(newSrc, Fnew);
- if (!PH) {
- // Update statistics
- ++NullBoundsChecks;
- return Dest;
- }
-
- //
- // Get the DSGraph of the enclosing function and get the corresponding
- // DSNode.
- //
- DSGraph & TDG = getDSGraph(*F);
- DSNode * Node = TDG.getNodeForValue(I).getNode();
-
- //
- // Determine whether an alignment check is needed. This occurs when a DSNode
- // is type unknown (collapsed) but has pointers to type known (uncollapsed)
- // DSNodes.
- //
- if (preSCPass->nodeNeedsAlignment (Node)) {
- ++AlignChecks;
- }
-
- // If there is no DSNode, do not perform a check
- if (!Node) return Dest;
-
- // If we do not know the allocation site, don't bother checking it
- if (!(isNodeRegistered (Node)))
- return Dest;
-
- // Record statistics on the incomplete checks we do. Note that a node may
- // be counted more than once.
- if (Node->isIncomplete())
- ++IBoundsChecks;
- if (Node->isUnknownNode())
- ++UBoundsChecks;
- if (Node->isAllocaNode())
- ++ABoundsChecks;
-
- //
- // Cast the pool handle, source and destination pointers into the correct
- // type for the call instruction.
- //
- Value * SrcCast = Src;
- Value * DestCast = Dest;
- if (Src->getType() != PointerType::get(Type::SByteTy))
- SrcCast = new CastInst (Src, PointerType::get(Type::SByteTy),
- "castsrc", InsertPt);
- if (Dest->getType() != PointerType::get(Type::SByteTy))
- DestCast = new CastInst (Dest, PointerType::get(Type::SByteTy),
- "castdst", InsertPt);
- if (PH->getType() != PointerType::get(Type::SByteTy))
- PH = new CastInst (PH, PointerType::get(Type::SByteTy),
- "castph", InsertPt);
-
- AddedValues.insert(DestCast);
-
- //
- // Insert the bounds check.
- //
- Value * CI;
- if (EnableSplitChecks) {
- std::vector<Value *> args(1, PH);
- args.push_back (SrcCast);
- if ((Node == 0) ||
- (Node->isAllocaNode()) ||
- (Node->isIncomplete()) ||
- (Node->isUnknownNode()))
- CI = new CallInst(UIgetBounds, args, "uibc",InsertPt);
- else
- CI = new CallInst(getBounds, args, "bc", InsertPt);
- std::vector<Value *> boundsargs(1, CI);
- Instruction * LowerBound = new CallInst(getBegin, boundsargs, "gb", InsertPt);
- Instruction * UpperBound = new CallInst(getEnd, boundsargs, "ge", InsertPt);
- Value * EC3 = addExactCheck3 (LowerBound, DestCast, UpperBound, InsertPt);
- AddedValues.insert(EC3);
- if (EC3->getType() != Dest->getType())
- EC3 = new CastInst(EC3, Dest->getType(), EC3->getName(), InsertPt);
- AddedValues.insert(EC3);
- // Replace all uses of the original pointer with the result of the exactcheck.
- // This ensures that the check will not get dead code eliminated.
- Value::use_iterator UI = Dest->use_begin();
- for (; UI != Dest->use_end(); ++UI) {
- if (AddedValues.find(*UI) == AddedValues.end())
- UI->replaceUsesOfWith (Dest,EC3);
- }
- CI = EC3;
- } else {
- std::vector<Value *> args(1, PH);
- args.push_back (SrcCast);
- args.push_back (DestCast);
- if ((Node == 0) ||
- (Node->isAllocaNode()) ||
- (Node->isIncomplete()) ||
- (Node->isUnknownNode()))
- CI = new CallInst(UIBoundsCheck, args, "uibc",InsertPt);
- else
- CI = new CallInst(BoundsCheck, args, "bc", InsertPt);
- }
-
- //
- // Record that this value was checked.
- //
- CheckedValues.insert (Dest);
- CheckedValues.insert (CI);
-
- // Update statistics
- ++BoundsChecks;
- return CI;
-}
-
-//
-// Method: getOrCreateFunctionTable()
-//
-// Description:
-// Given a DSNode, return a global variable containing an array of the
-// function pointers within that DSNode. If this global variable does not
-// exist, create it and modify poolcheckglobals() to register it with its
-// MetaPool.
-//
-GlobalVariable *
-InsertPoolChecks::getOrCreateFunctionTable (DSNode * Node, Value * PH,
- Module * M) {
- // Determine if we have already created such a global.
- if (FuncListMap.count (PH)) {
- return FuncListMap[PH];
- }
-
- // Get the globals list corresponding to the node
- std::vector<Function *> FuncList;
- Node->addFullFunctionList(FuncList);
- unsigned num = FuncList.size();
-
- // Create a global array of void pointers containing the list of possible
- // function targets.
- std::vector<Function *>::iterator flI= FuncList.begin(), flE = FuncList.end();
- const Type* csiType = Type::getPrimitiveType(Type::UIntTyID);
- Value *NumArg = ConstantInt::get(csiType, num);
- Type *VoidPtrType = PointerType::get(Type::SByteTy);
- std::vector<Constant *> Targets;
-
- for (; flI != flE ; ++flI) {
- Function *func = *flI;
- Constant *CastfuncI = ConstantExpr::getCast (func, VoidPtrType);
- Targets.push_back(CastfuncI);
- }
-
- ArrayType * TableType = ArrayType::get (VoidPtrType, num);
- Constant * TableInit = ConstantArray::get (TableType, Targets);
- GlobalVariable * Table = new GlobalVariable (TableType, true, GlobalValue::InternalLinkage, TableInit, "functargets", M);
- Value * TableCast = ConstantExpr::getCast (Table, PointerType::get(VoidPtrType));
-
- //
- // Add an instruction to poolcheckglobals() to register this table of
- // functions with the MetaPool.
- //
- std::vector<const Type*> Vt;
- const FunctionType* RFT = FunctionType::get(Type::VoidTy, Vt, false);
- Function * RegFunc = M->getOrInsertFunction("poolcheckglobals", RFT);
- BasicBlock* BB;
- if (RegFunc->empty()) {
- BasicBlock* BB = new BasicBlock("reg", RegFunc);
- new ReturnInst(BB);
- } else {
- BB = &(RegFunc->getEntryBlock());
- }
-
- Instruction * InsertPt = BB->getTerminator();
- Value * CastPH = new CastInst(PH, VoidPtrType, "casted", InsertPt);
- std::vector<Value *> args;
- args.push_back (CastPH);
- args.push_back (NumArg);
- args.push_back (TableCast);
- new CallInst(FuncRegister, args, "", InsertPt);
-
- //
- // Insert the DSNode and Table into the map.
- //
- FuncListMap.insert (make_pair(PH,Table));
- return Table;
-}
-
-//
-// Method: insertFunctionCheck()
-//
-// Description:
-// Insert a run-time check on the argument to an indirect call instruction.
-//
-void
-InsertPoolChecks::insertFunctionCheck (CallInst * CI) {
- if (DisableFuncChecks)
- return;
-
- // Get the containing function and the function pointer.
- Function * F = CI->getParent()->getParent();
- Value * FuncPointer = CI->getCalledValue();
-
- // Try to remove any encapsulating casts to get to the original instruction
- ConstantExpr *cExpr;
- while ((cExpr = dyn_cast<ConstantExpr>(FuncPointer)) &&
- (cExpr->getOpcode() == Instruction::Cast))
- FuncPointer = cExpr->getOperand(0);
-
- //
- // Determine if the function pointer came from a load instruction that loaded
- // its value from a type known pool. If it is, it does not need a check.
- //
- if (LoadInst * LI = dyn_cast<LoadInst>(FuncPointer)) {
- DSNode * LoadNode = getDSNode (LI->getPointerOperand(), F);
- if ((LoadNode) && (!(LoadNode->isNodeCompletelyFolded())))
- return;
- }
-
- //
- // Get the DSNode and Pool handle for the call instruction.
- //
- Value *PH = getPoolHandle (FuncPointer, F);
- if (!PH) {
- // Update statistics
- ++NullBoundsChecks;
- return;
- }
- DSNode* Node = getDSNode(FuncPointer, F);
-
- //
- // If the node is incomplete, then the call targets associated with the
- // DSNode may be missing valid function targets. In that case, do not
- // insert a check.
- //
- if ((!EnableUnknownChecks) && (Node->isIncomplete())) {
- ++MissedFuncChecks;
- return;
- }
-
- // Get the globals list corresponding to the node
- std::vector<Function *> FuncList;
- Node->addFullFunctionList(FuncList);
- unsigned num = FuncList.size();
-
- //
- // Insert a call to one of the function check functions, depending upon
- // the number of functions we must check against.
- //
- if (num == 0) {
- ++ZeroFuncChecks;
- return;
- }
-
- // Update statistics on the number of indirect call checks.
- ++FuncChecks;
-
- std::vector<Function *>::iterator flI= FuncList.begin(), flE = FuncList.end();
- const Type* csiType = Type::getPrimitiveType(Type::UIntTyID);
- Value *NumArg = ConstantInt::get(csiType, num);
- Type *VoidPtrType = PointerType::get(Type::SByteTy);
-
- if (num < 7) {
- const Type* csiType = Type::getPrimitiveType(Type::UIntTyID);
- Value *NumArg = ConstantInt::get(csiType, num);
-
- CastInst *CastVI =
- new CastInst(FuncPointer, VoidPtrType, "casted", (Instruction *)(CI));
-
- std::vector<Value *> args(1, NumArg);
- args.push_back(CastVI);
- for (; flI != flE ; ++flI) {
- Function *func = *flI;
- CastInst *CastfuncI =
- new CastInst(func, VoidPtrType, "casted", (Instruction *)(CI));
- args.push_back(CastfuncI);
- }
- for (unsigned index = num; index < 7; ++index)
- args.push_back (ConstantPointerNull::get (PointerType::get (Type::SByteTy)));
- new CallInst(FunctionCheck, args,"", (Instruction *)(CI));
- } else if (num < 21) {
- // Create the first two arguments for the function check call
- std::vector<Value *> args(1, NumArg);
- CastInst *CastVI =
- new CastInst(FuncPointer, VoidPtrType, "casted", (Instruction *)(CI));
- args.push_back(CastVI);
-
- // Create a global array of void pointers containing the list of possible
- // function targets.
- GlobalVariable * Table = getOrCreateFunctionTable (Node, PH, F->getParent());
-
- CastInst *CastTable =
- new CastInst(Table,
- PointerType::get(VoidPtrType), "casted", (Instruction *)(CI));
-
- args.push_back(CastTable);
- new CallInst(FunctionCheckT, args, "", (Instruction *)(CI));
- } else {
- // Create a global array of void pointers containing the list of possible
- // function targets.
- getOrCreateFunctionTable (Node, PH, F->getParent());
-
- // Create the first two arguments for the function check call
- PH = new CastInst (PH, VoidPtrType, "casted", (Instruction *)(CI));
- CastInst *CastVI =
- new CastInst(FuncPointer, VoidPtrType, "casted", (Instruction *)(CI));
- std::vector<Value *> args(1, PH);
- args.push_back(CastVI);
-
- new CallInst(FunctionCheckG, args,"", (Instruction *)(CI));
- }
-}
-
-//
-// Function: addExactCheck2()
-//
-// Description:
-// Utility routine that inserts a call to exactcheck2().
-//
-// Inputs:
-// BasePointer - An LLVM Value representing the base of the object to check.
-// Result - An LLVM Value representing the pointer to check.
-// Bounds - An LLVM Value representing the bounds of the check.
-// InsertPt - The instruction before which to insert the check.
-//
-void
-InsertPoolChecks::addExactCheck2 (Value * BasePointer,
- Value * Result,
- Value * Bounds,
- Instruction * InsertPt) {
- Value * ResultPointer = Result;
-
- // The LLVM type for a void *
- Type *VoidPtrType = PointerType::get(Type::SByteTy);
-
- //
- // Cast the operands to the correct type.
- //
- if (BasePointer->getType() != VoidPtrType)
- BasePointer = new CastInst(BasePointer, VoidPtrType,
- BasePointer->getName()+".ec2.casted",
- InsertPt);
-
- if (ResultPointer->getType() != VoidPtrType)
- ResultPointer = new CastInst(ResultPointer, VoidPtrType,
- ResultPointer->getName()+".ec2.casted",
- InsertPt);
-
- Value * CastBounds = Bounds;
- if (Bounds->getType() != Type::UIntTy)
- CastBounds = new CastInst(Bounds, Type::UIntTy,
- Bounds->getName()+".ec.casted", InsertPt);
-
- //
- // Create the call to exactcheck2().
- //
- std::vector<Value *> args(1, BasePointer);
- args.push_back(ResultPointer);
- args.push_back(CastBounds);
- Instruction * CI;
- CI = new CallInst(ExactCheck2, args, "", InsertPt);
-
- //
- // Record that this value was checked.
- //
- CheckedValues.insert (Result);
-
-#if 0
- //
- // Replace the old pointer with the return value of exactcheck2(); this
- // prevents GCC from removing it completely.
- //
- if (CI->getType() != GEP->getType())
- CI = new CastInst (CI, GEP->getType(), GEP->getName(), InsertPt);
-
- Value::use_iterator UI = GEP->use_begin();
- for (; UI != GEP->use_end(); ++UI) {
- if (((*UI) != CI) && ((*UI) != ResultPointer))
- UI->replaceUsesOfWith (GEP, CI);
- }
-#endif
-
- // Update statistics
- ++ExactChecks;
- return;
-}
-
-//
-// Function: addExactCheck3()
-//
-// Description:
-// Utility routine that inserts a call to exactcheck3().
-//
-// Inputs:
-// Source - The pointer that is the lower bound of the array.
-// Result - The pointer that we wish to check.
-// Bounds - The length of the array in bytes.
-// InsertPt - The instruction before which to insert the check.
-//
-Value *
-InsertPoolChecks::addExactCheck3 (Value * Source,
- Value * Result,
- Value * Bounds,
- Instruction * InsertPt) {
- // The LLVM type for a void *
- Type *VoidPtrType = PointerType::get(Type::SByteTy);
-
- // Update statistics
- ++ExactChecks;
-
- //
- // Cast the operands to the correct type.
- //
- Value * BasePointer = Source;
- if (BasePointer->getType() != VoidPtrType)
- BasePointer = new CastInst(BasePointer, VoidPtrType,
- BasePointer->getName()+".ec3.base.casted",
- InsertPt);
-
- Value * ResultPointer = Result;
- if (ResultPointer->getType() != VoidPtrType)
- ResultPointer = new CastInst(Result, VoidPtrType,
- Result->getName()+".ec3.result.casted",
- InsertPt);
-
- Value * CastBounds = Bounds;
- if (Bounds->getType() != VoidPtrType)
- CastBounds = new CastInst(Bounds, VoidPtrType,
- Bounds->getName()+".ec3.end.casted", InsertPt);
-
- std::vector<Value *> args(1, BasePointer);
- args.push_back(ResultPointer);
- args.push_back(CastBounds);
-
- //
- // Record that this value was checked.
- //
- CheckedValues.insert (Result);
- return new CallInst(ExactCheck3, args, "ec3", InsertPt);
-}
-
-//
-// Function: addExactCheck()
-//
-// Description:
-// Utility routine that inserts a call to exactcheck(). This function can
-// perform some optimization be determining if the arguments are constant.
-// If they are, we can forego inserting the call.
-//
-// Inputs:
-// Index - An LLVM Value representing the index of the access.
-// Bounds - An LLVM Value representing the bounds of the check.
-//
-void
-InsertPoolChecks::addExactCheck (Value * Pointer,
- Value * Index, Value * Bounds,
- Instruction * InsertPt) {
- //
- // Record that this value was checked.
- //
- CheckedValues.insert (Pointer);
-
- //
- // Attempt to determine statically if this check will always pass; if so,
- // then don't bother doing it at run-time.
- //
- ConstantInt * CIndex = dyn_cast<ConstantInt>(Index);
- ConstantInt * CBounds = dyn_cast<ConstantInt>(Bounds);
- if (CIndex && CBounds) {
- int index = CIndex->getSExtValue();
- int bounds = CBounds->getSExtValue();
- assert ((index >= 0) && "exactcheck: const negative index");
- assert ((index < bounds) && "exactcheck: const out of range");
-
- // Update stats and return
- ++ConstExactChecks;
- return;
- }
-
- //
- // Second, cast the operands to the correct type.
- //
- Value * CastIndex = Index;
- if (Index->getType() != Type::IntTy)
- CastIndex = new CastInst(Index, Type::IntTy,
- Index->getName()+".ec.casted", InsertPt);
-
- Value * CastBounds = Bounds;
- if (Bounds->getType() != Type::IntTy)
- CastBounds = new CastInst(Bounds, Type::IntTy,
- Bounds->getName()+".ec.casted", InsertPt);
-
- const Type *VoidPtrType = PointerType::get(Type::SByteTy);
- Value * CastResult = Pointer;
- if (CastResult->getType() != VoidPtrType)
- CastResult = new CastInst(CastResult, VoidPtrType,
- CastResult->getName()+".ec.casted", InsertPt);
-
- std::vector<Value *> args(1, CastIndex);
- args.push_back(CastBounds);
- args.push_back(CastResult);
- Instruction * CI = new CallInst(ExactCheck, args, "ec", InsertPt);
-
-#if 0
- //
- // Replace the old index with the return value of exactcheck(); this
- // prevents GCC from removing it completely.
- //
- Value * CastCI = CI;
- if (CI->getType() != GEP->getType())
- CastCI = new CastInst (CI, GEP->getType(), GEP->getName(), InsertPt);
-
- Value::use_iterator UI = GEP->use_begin();
- for (; UI != GEP->use_end(); ++UI) {
- if (((*UI) != CI) && ((*UI) != CastResult))
- UI->replaceUsesOfWith (GEP, CastCI);
- }
-#endif
-
- // Update statistics
- ++ExactChecks;
- return;
-}
-
-//
-// Function: addExactCheck()
-//
-// Description:
-// Utility routine that inserts a call to exactcheck(). This function can
-// perform some optimization be determining if the arguments are constant.
-// If they are, we can forego inserting the call.
-//
-// Inputs:
-// GEP - The GEP for which the check will be done.
-// Index - An LLVM Value representing the index of the access.
-// Bounds - An LLVM Value representing the bounds of the check.
-//
-void
-InsertPoolChecks::addExactCheck (Instruction * GEP,
- Value * Index, Value * Bounds) {
- //
- // Record that this value was checked.
- //
- CheckedValues.insert (GEP);
-
- // Upper and lower values on the index and bounds
- int index_lower;
- int index_upper;
- int bounds_lower;
- int bounds_upper;
-
- //
- // First, attempt to determine statically whether the check will always pass.
- // If so, then don't bother doing it at run-time.
- //
- ConstantInt * CIndex = dyn_cast<ConstantInt>(Index);
- ConstantInt * CBounds = dyn_cast<ConstantInt>(Bounds);
- if (CIndex && CBounds) {
- int index = CIndex->getSExtValue();
- int bounds = CBounds->getSExtValue();
- assert ((index >= 0) && "exactcheck: const negative index");
- assert ((index < bounds) && "exactcheck: const out of range");
-
- // Update stats and return
- ++ConstExactChecks;
- return;
- } else if (CBounds) {
- int bounds = CBounds->getSExtValue();
- SCEVHandle SCEVIndex = scevPass->getSCEV (Index);
- ConstantRange IndexRange = SCEVIndex->getValueRange();
- if (!(IndexRange.isWrappedSet())) {
- int index_lower = IndexRange.getLower()->getSExtValue();
- int index_upper = IndexRange.getUpper()->getSExtValue();
- int bounds_lower = bounds;
- int bounds_upper = bounds;
-
- if ((index_lower >= 0) && (index_upper < bounds_lower)) {
- ++ConstExactChecks;
- return;
- }
- }
- }
-
- SCEVHandle SCEVIndex = scevPass->getSCEV (Index);
- SCEVHandle SCEVBounds = scevPass->getSCEV (Bounds);
- ConstantRange BoundsRange = SCEVBounds->getValueRange();
- ConstantRange IndexRange = SCEVIndex->getValueRange();
- if ((!(IndexRange.isWrappedSet())) && (!(BoundsRange.isWrappedSet()))) {
- int index_lower = IndexRange.getLower()->getSExtValue();
- int index_upper = IndexRange.getUpper()->getSExtValue();
- int bounds_lower = BoundsRange.getLower()->getSExtValue();
- int bounds_upper = BoundsRange.getUpper()->getSExtValue();
-
- if ((index_lower >= 0) && (index_upper < bounds_lower)) {
- ++ConstExactChecks;
- return;
- }
- }
-
- //
- // Cast the operands to the correct type.
- //
- Instruction * InsertPt = GEP->getNext();
-
- Value * CastIndex = Index;
- if (Index->getType() != Type::IntTy)
- CastIndex = new CastInst(Index, Type::IntTy,
- Index->getName()+".ec.casted", InsertPt);
-
- Value * CastBounds = Bounds;
- if (Bounds->getType() != Type::IntTy)
- CastBounds = new CastInst(Bounds, Type::IntTy,
- Bounds->getName()+".ec.casted", InsertPt);
-
- const Type *VoidPtrType = PointerType::get(Type::SByteTy);
- Value * CastResult = GEP;
- if (CastResult->getType() != VoidPtrType)
- CastResult = new CastInst(CastResult, VoidPtrType,
- CastResult->getName()+".ec.casted", InsertPt);
-
- std::vector<Value *> args(1, CastIndex);
- args.push_back(CastBounds);
- args.push_back(CastResult);
- Instruction * CI = new CallInst(ExactCheck, args, "ec", InsertPt);
-
- //
- // Replace the old index with the return value of exactcheck(); this
- // prevents GCC from removing it completely.
- //
-#if 0
- Value * CastCI = CI;
- if (CI->getType() != GEP->getType())
- CastCI = new CastInst (CI, GEP->getType(), GEP->getName(), InsertPt);
-
- Value::use_iterator UI = GEP->use_begin();
- for (; UI != GEP->use_end(); ++UI) {
- if (((*UI) != CI) && ((*UI) != CastResult))
- UI->replaceUsesOfWith (GEP, CastCI);
- }
-#endif
-
- // Update statistics
- ++ExactChecks;
- return;
-}
-
-//
-// Function: isEligableForExactCheck()
-//
-// Return value:
-// true - This value is eligable for an exactcheck.
-// false - This value is not eligable for an exactcheck.
-//
-static inline bool
-isEligableForExactCheck (Value * Pointer) {
- if ((isa<AllocaInst>(Pointer)) || (isa<GlobalVariable>(Pointer)))
- return true;
-
- if (CallInst* CI = dyn_cast<CallInst>(Pointer)) {
- if (CI->getCalledFunction() &&
- (CI->getCalledFunction()->getName() == "__vmalloc" ||
- CI->getCalledFunction()->getName() == "kmalloc" ||
- CI->getCalledFunction()->getName() == "kmem_cache_alloc" ||
- CI->getCalledFunction()->getName() == "__alloc_bootmem")) {
- return true;
- }
- }
-
- return false;
-}
-
-//
-// Function: findCheckedPointer()
-//
-// Description:
-// Given a pointer value, attempt to determine whether the pointer or all of
-// the instructions that created it have been checked.
-//
-bool
-InsertPoolChecks::findCheckedPointer (Value * PointerOperand) {
- Value * SourcePointer = PointerOperand;
-
- while (CheckedValues.find (SourcePointer) == CheckedValues.end()) {
- // Check for cast constant expressions and instructions
- if (ConstantExpr * cExpr = dyn_cast<ConstantExpr>(SourcePointer)) {
- if (cExpr->getOpcode() == Instruction::Cast) {
- if (isa<PointerType>(cExpr->getOperand(0)->getType())) {
- SourcePointer = cExpr->getOperand(0);
- continue;
- }
- }
- // We cannot handle this expression; break out of the loop
- break;
- }
-
- if (CastInst * CastI = dyn_cast<CastInst>(SourcePointer)) {
- if (isa<PointerType>(CastI->getOperand(0)->getType())) {
- SourcePointer = CastI->getOperand(0);
- continue;
- }
- break;
- }
-
- // We can't scan through any more instructions; give up
- break;
- }
-
- //
- // If the pointer is a GEP, then as long as it has a DSNode, it has been
- // checked or proven safe.
- //
- Instruction * I;
- if ((I = dyn_cast<GetElementPtrInst>(SourcePointer)) &&
- (getDSNode (I, I->getParent()->getParent())) &&
- (getPoolHandle(I, I->getParent()->getParent()))) {
- return true;
- }
-#if 0
- return (CheckedValues.find (SourcePointer) != CheckedValues.end());
-#else
- // Return false; check must dominate load/store.
- return false;
-#endif
-}
-
-//
-// Function: findSourcePointer()
-//
-// Description:
-// Given a pointer value, attempt to find a source of the pointer that can
-// be used in an exactcheck().
-//
-// Outputs:
-// indexed - Flags whether the data flow went through a indexing operation
-// (i.e. a GEP). This value is always written.
-//
-static Value *
-findSourcePointer (Value * PointerOperand, bool & indexed) {
- //
- // Attempt to look for the originally allocated object by scanning the data
- // flow up.
- //
- indexed = false;
- Value * SourcePointer = PointerOperand;
- Value * OldSourcePointer = 0;
- while (!isEligableForExactCheck (SourcePointer)) {
- assert (OldSourcePointer != SourcePointer);
- OldSourcePointer = SourcePointer;
- // Check for GEP and cast constant expressions
- if (ConstantExpr * cExpr = dyn_cast<ConstantExpr>(SourcePointer)) {
- if ((cExpr->getOpcode() == Instruction::Cast) ||
- (cExpr->getOpcode() == Instruction::GetElementPtr)) {
- if (isa<PointerType>(cExpr->getOperand(0)->getType())) {
- SourcePointer = cExpr->getOperand(0);
- continue;
- }
- }
- // We cannot handle this expression; break out of the loop
- break;
- }
-
- // Check for GEP and cast instructions
- if (GetElementPtrInst * G = dyn_cast<GetElementPtrInst>(SourcePointer)) {
- SourcePointer = G->getPointerOperand();
- indexed = true;
- continue;
- }
-
- if (CastInst * CastI = dyn_cast<CastInst>(SourcePointer)) {
- if (isa<PointerType>(CastI->getOperand(0)->getType())) {
- SourcePointer = CastI->getOperand(0);
- continue;
- }
- break;
- }
-
- // Check for call instructions to exact checks.
- CallInst * CI1;
- if ((CI1 = dyn_cast<CallInst>(SourcePointer)) &&
- (CI1->getCalledFunction()) &&
- (CI1->getCalledFunction()->getName() == "exactcheck3")) {
- SourcePointer = CI1->getOperand (2);
- continue;
- }
-
- // We can't scan through any more instructions; give up
- break;
- }
-
- if (isEligableForExactCheck (SourcePointer))
- PointerOperand = SourcePointer;
-
- return PointerOperand;
-}
-
-//
-// Function: insertExactCheck()
-//
-// Description:
-// Attepts to insert an efficient, accurate array bounds check for the given
-// GEP instruction; this check will not use Pools are MetaPools.
-//
-// Return value:
-// true - An exactcheck() was successfully added.
-// false - An exactcheck() could not be added; a more extensive check will be
-// needed.
-//
-bool
-InsertPoolChecks::insertExactCheck (GetElementPtrInst * GEP) {
- // The GEP instruction casted to the correct type
- Instruction *Casted = GEP;
-
- // The pointer operand of the GEP expression
- Value * PointerOperand = GEP->getPointerOperand();
-
- //
- // Get the DSNode for the instruction
- //
- Function *F = GEP->getParent()->getParent();
- DSGraph & TDG = getDSGraph(*F);
- DSNode * Node = TDG.getNodeForValue(GEP).getNode();
- assert (Node && "boundscheck: DSNode is NULL!");
-
- //
- // Determine whether an alignment check is needed. This occurs when a DSNode
- // is type unknown (collapsed) but has pointers to type known (uncollapsed)
- // DSNodes.
- //
- if (preSCPass->nodeNeedsAlignment (Node)) {
- ++AlignChecks;
- }
-
-#if 0
- // Debugging: See if we're missing exactcheck opportunities
- if (isa<SelectInst>(PointerOperand))
- std::cerr << "LLVA: EC: Select Inst\n";
-
- if (isa<GetElementPtrInst>(PointerOperand))
- std::cerr << "LLVA: EC: GEP: In " << F->getName() << "\n";
-
- CallInst * CI1;
- if ((CI1 = dyn_cast<CallInst>(PointerOperand)) &&
- (CI1->getCalledFunction()) &&
- (CI1->getCalledFunction()->getName() == "exactcheck3"))
- std::cerr << "LLVA: EC: GEP: Hidden by ec3: In " << F->getName() << "\n";
-
- PHINode * PN = 0;
- if (PN = dyn_cast<PHINode>(PointerOperand)) {
- std::cerr << "LLVA: EC: PHI\n";
- for (unsigned index = 0; index < PN->getNumIncomingValues(); ++index) {
- std::cerr << "LLVA: " << *(PN->getIncomingValue(index)) << std::endl;
- }
- }
-#endif
-
- //
- // Attempt to find the object which we need to check.
- //
- bool WasIndexed = true;
- PointerOperand = findSourcePointer (PointerOperand, WasIndexed);
-
- //
- // Ensure the pointer operand really is a pointer.
- //
- if (!isa<PointerType>(PointerOperand->getType()))
- return false;
-
- if (GlobalVariable *GV = dyn_cast<GlobalVariable>(PointerOperand)) {
- //
- // Attempt to remove checks on GEPs that only index into structures.
- // These criteria must be met:
- // 1) The pool must be Type-Homogoneous.
- //
-#if 0
- if ((!(Node->isNodeCompletelyFolded())) &&
- (indexesStructsOnly (GEP))) {
- ++StructGEPsRemoved;
- return true;
- }
-#endif
-
- //
- // Attempt to use a call to exactcheck() to check this value if it is a
- // global array with a non-zero size. We do not check zero length arrays
- // because in C they are often used to declare an external array of unknown
- // size as follows:
- // extern struct foo the_array[];
- //
- const ArrayType *AT = dyn_cast<ArrayType>(GV->getType()->getElementType());
- if ((!WasIndexed) && AT && (AT->getNumElements())) {
- // we need to insert an actual check
- // It could be a select instruction
- // First get the size
- // This only works for one or two dimensional arrays
- if (GEP->getNumOperands() == 2) {
- Value *secOp = GEP->getOperand(1);
-
- const Type* csiType = Type::getPrimitiveType(Type::IntTyID);
- ConstantInt * Bounds = ConstantInt::get(csiType,AT->getNumElements());
- addExactCheck (GEP, secOp, Bounds);
- return true;
- } else if (GEP->getNumOperands() == 3) {
- if (ConstantInt *COP = dyn_cast<ConstantInt>(GEP->getOperand(1))) {
- //FIXME assuming that the first array index is 0
- assert((COP->getZExtValue() == 0) && "non zero array index\n");
-
- Value * secOp = GEP->getOperand(2);
- const Type* csiType = Type::getPrimitiveType(Type::IntTyID);
- ConstantInt * Bounds = ConstantInt::get(csiType,AT->getNumElements());
- addExactCheck (GEP, secOp, Bounds);
- return true;
- } else {
- // TODO:
- // Handle non constant index two dimensional arrays later
- Value* Size=ConstantInt::get(Type::IntTy, TD->getTypeSize(GV->getType()));
- addExactCheck2 (PointerOperand, GEP, Size, GEP->getNext());
- return true;
- }
- } else {
- // Handle Multi dimensional cases later
- Value* AllocSize=ConstantInt::get(Type::IntTy, TD->getTypeSize(GV->getType()->getElementType()));
- addExactCheck2 (PointerOperand, GEP, AllocSize, GEP->getNext());
- return true;
- GEP->dump();
- ++MissedMultDimArrayChecks;
- }
- DEBUG(std::cerr << " Global variable ok \n");
- } else {
- Value* Size=ConstantInt::get(Type::IntTy, TD->getTypeSize(GV->getType()));
- addExactCheck2 (PointerOperand, GEP, Size, GEP->getNext());
- return true;
- }
- }
-
- //
- // If the pointer was generated by a dominating alloca instruction, we can
- // do an exactcheck on it, too.
- //
- if (AllocaInst *AI = dyn_cast<AllocaInst>(PointerOperand)) {
- //
- // Attempt to remove checks on GEPs that only index into structures.
- // These criteria must be met:
- // 1) The pool must be Type-Homogoneous.
- //
-#if 0
- if ((!(Node->isNodeCompletelyFolded())) &&
- (indexesStructsOnly (GEP))) {
- ++StructGEPsRemoved;
- return true;
- }
-#endif
-
- const Type * AllocaType = AI->getAllocatedType();
- Value *AllocSize=ConstantInt::get(Type::IntTy, TD->getTypeSize(AllocaType));
-
- if (AI->isArrayAllocation())
- AllocSize = BinaryOperator::create(Instruction::Mul,
- AllocSize,
- AI->getOperand(0), "sizetmp", GEP);
-
- addExactCheck2 (PointerOperand, GEP, AllocSize, GEP->getNext());
- return true;
- }
-
- //
- // If the pointer was an allocation, we should be able to do exact checks
- //
- CallInst* CI = dyn_cast<CallInst>(PointerOperand);
- if (CI && (CI->getCalledFunction())) {
- if ((CI->getCalledFunction()->getName() == "__vmalloc") ||
- (CI->getCalledFunction()->getName() == "kmalloc") ||
- (CI->getCalledFunction()->getName() == "__alloc_bootmem")) {
- //
- // Attempt to remove checks on GEPs that only index into structures.
- // These criteria must be met:
- // 1) The pool must be Type-Homogoneous.
- //
-#if 0
- if ((!(Node->isNodeCompletelyFolded())) &&
- (indexesStructsOnly (GEP))) {
- ++StructGEPsRemoved;
- return true;
- }
-#endif
-
- Value* Cast = new CastInst(CI->getOperand(1), Type::IntTy, "", GEP);
- addExactCheck2(PointerOperand, GEP, Cast, GEP->getNext());
- return true;
- } else if (CI->getCalledFunction()->getName() == "kmem_cache_alloc") {
- // Insert a call to kmem_get_cachesize() to determine the size of the
- // allocated object
- const Type * VoidPtrType = PointerType::get(Type::SByteTy);
- Value* VP = castTo (CI->getOperand(1), VoidPtrType, GEP);
- CallInst *len = new CallInst(KmemCachegetSize, VP, "", GEP);
-
- // Add the exactcheck
- Value* CastLen = castTo (len, Type::IntTy, GEP);
- addExactCheck2(PointerOperand, GEP, CastLen, GEP->getNext());
- }
- }
-
- //
- // If the pointer is to a structure, we may be able to perform a simple
- // exactcheck on it, too, unless the array is at the end of the structure.
- // Then, we assume it's a variable length array and must be full checked.
- //
-#if 0
- if (const PointerType * PT = dyn_cast<PointerType>(PointerOperand->getType()))
- if (const StructType *ST = dyn_cast<StructType>(PT->getElementType())) {
- const Type * CurrentType = ST;
- ConstantInt * C;
- for (unsigned index = 2; index < GEP->getNumOperands() - 1; ++index) {
- //
- // If this GEP operand is a constant, index down into the next type.
- //
- if (C = dyn_cast<ConstantInt>(GEP->getOperand(index))) {
- if (const StructType * ST2 = dyn_cast<StructType>(CurrentType)) {
- CurrentType = ST2->getElementType(C->getZExtValue());
- continue;
- }
-
- if (const ArrayType * AT = dyn_cast<ArrayType>(CurrentType)) {
- CurrentType = AT->getElementType();
- continue;
- }
-
- // We don't know how to handle this type of element
- break;
- }
-
- //
- // If the GEP operand is not constant and points to an array type,
- // then try to insert an exactcheck().
- //
- const ArrayType * AT;
- if ((AT = dyn_cast<ArrayType>(CurrentType)) && (AT->getNumElements())) {
- const Type* csiType = Type::getPrimitiveType(Type::IntTyID);
- ConstantInt * Bounds = ConstantInt::get(csiType,AT->getNumElements());
- addExactCheck (GEP, GEP->getOperand (index), Bounds);
- return true;
- }
- }
- }
-#endif
-
- /*
- * We were not able to insert a call to exactcheck().
- */
- return false;
-}
-
-//
-// Function: insertExactCheck()
-//
-// Description:
-// Attepts to insert an efficient, accurate array bounds check for the given
-// GEP instruction; this check will not use Pools are MetaPools.
-//
-// Inputs:
-// I - The instruction for which we are adding the check.
-// Src - The pointer that needs to be checked.
-// Size - The size, in bytes, that will be read/written by instruction I.
-// InsertPt - The instruction before which the check should be inserted.
-//
-// Return value:
-// true - An exactcheck() was successfully added.
-// false - An exactcheck() could not be added; a more extensive check will be
-// needed.
-//
-bool
-InsertPoolChecks::insertExactCheck (Instruction * I,
- Value * Src,
- Value * Size,
- Instruction * InsertPt) {
- // The pointer operand of the GEP expression
- Value * PointerOperand = Src;
-
- //
- // Get the DSNode for the instruction
- //
-#if 1
- Function *F = I->getParent()->getParent();
- DSGraph & TDG = getDSGraph(*F);
- DSNode * Node = TDG.getNodeForValue(I).getNode();
- if (!Node)
- return false;
-#endif
-
- //
- // Determine whether an alignment check is needed. This occurs when a DSNode
- // is type unknown (collapsed) but has pointers to type known (uncollapsed)
- // DSNodes.
- //
- if (preSCPass->nodeNeedsAlignment (Node)) {
- ++AlignChecks;
- }
-
- //
- // Attempt to find the original object for which this check applies.
- // This involves unpeeling casts, GEPs, etc.
- //
- bool WasIndexed = true;
- PointerOperand = findSourcePointer (PointerOperand, WasIndexed);
-
- //
- // Ensure the pointer operand really is a pointer.
- //
- if (!isa<PointerType>(PointerOperand->getType()))
- {
- return false;
- }
-
- //
- // Attempt to use a call to exactcheck() to check this value if it is a
- // global array with a non-zero size. We do not check zero length arrays
- // because in C they are often used to declare an external array of unknown
- // size as follows:
- // extern struct foo the_array[];
- //
- if (GlobalVariable *GV = dyn_cast<GlobalVariable>(PointerOperand)) {
- const Type* csiType = Type::getPrimitiveType(Type::IntTyID);
- unsigned int arraysize = TD->getTypeSize(GV->getType()->getElementType());
- ConstantInt * Bounds = ConstantInt::get(csiType, arraysize);
- if (WasIndexed)
- addExactCheck2 (PointerOperand, Src, Bounds, InsertPt);
- else
- addExactCheck (Src, Size, Bounds, InsertPt);
- return true;
- }
-
- //
- // If the pointer was generated by a dominating alloca instruction, we can
- // do an exactcheck on it, too.
- //
- if (AllocaInst *AI = dyn_cast<AllocaInst>(PointerOperand)) {
- const Type * AllocaType = AI->getAllocatedType();
- Value *AllocSize=ConstantInt::get(Type::IntTy, TD->getTypeSize(AllocaType));
-
- if (AI->isArrayAllocation())
- AllocSize = BinaryOperator::create(Instruction::Mul,
- AllocSize,
- AI->getOperand(0), "allocsize", InsertPt);
-
- if (WasIndexed)
- addExactCheck2 (PointerOperand, Src, AllocSize, InsertPt);
- else
- addExactCheck (Src, Size, AllocSize, InsertPt);
- return true;
- }
-
- //
- // If the pointer was an allocation, we should be able to do exact checks
- //
- if(CallInst* CI = dyn_cast<CallInst>(PointerOperand)) {
- if (CI->getCalledFunction() && (
- CI->getCalledFunction()->getName() == "__vmalloc" ||
- CI->getCalledFunction()->getName() == "kmalloc")) {
- Value* Cast = new CastInst(CI->getOperand(1), Type::IntTy, "allocsize", InsertPt);
- if (WasIndexed)
- addExactCheck2 (PointerOperand, Src, Cast, InsertPt);
- else
- addExactCheck (Src, Size, Cast, InsertPt);
- return true;
- }
- }
-
- //
- // We were not able to insert a call to exactcheck().
- //
- return false;
-}
-
-bool
-InsertPoolChecks::doInitialization (Module & M) {
- // Add the new poolcheck prototype
- addPoolCheckProto (M);
-
- return true;
-}
-
-bool
-InsertPoolChecks::doFinalization (Module & M) {
- // Insert code to register heap allocations with the correct MetaPool
- // and to register kernel pools with the correct MetaPool
- addHeapRegs (M);
-
- // Insert code to drop objects from MetaPools when they are freed by the
- // kernel allocators
- addObjFrees (M);
-
- return true;
-}
-
-bool
-InsertPoolChecks::runOnFunction (Function & F) {
- //
- // Retrieve references to all of the passes from which we will gather
- // information.
- //
- preSCPass = &getAnalysis<PreInsertPoolChecks>();
- cuaPass = &getAnalysis<ConvertUnsafeAllocas>();
- TD = &getAnalysis<TargetData>();
- scevPass = &getAnalysis<ScalarEvolution>();
- LI = &getAnalysis<LoopInfo>();
-#ifdef LLVA_KERNEL
- TDPass = &getAnalysis<TDDataStructures>();
-#else
- paPass = &getAnalysis<PoolAllocate>();
- equivPass = &(paPass->getECGraphs());
- efPass = &getAnalysis<EmbeCFreeRemoval>();
- TD = &getAnalysis<TargetData>();
-#endif
-
-#if 1
- // Transform the function
- if (!(F.isExternal())) TransformFunction (F);
- if (!DisableLSChecks) addLoadStoreChecks(F);
-#endif
-
- //
- // Update the statistics.
- //
- PoolChecks = NullChecks + FullChecks;
-
- return true;
-}
-
-void InsertPoolChecks::handleCallInst(CallInst *CI) {
- //
- // Determine if this is an indirect call. If so, insert a run-time check for
- // it.
- //
- if (!(CI->getCalledFunction()))
- insertFunctionCheck (CI);
-
- //
- // Check for intrinsic functions and add checks as necessary.
- //
- if (CI && (!DisableIntrinsicChecks)) {
- Value *Fop = CI->getOperand(0);
- Function *F = CI->getParent()->getParent();
-#ifdef LLVA_KERNEL
- std::string FuncName = Fop->getName();
- if ((FuncName == "llvm.memcpy.i32") ||
- (FuncName == "llvm.memcpy.i64") ||
- (FuncName == "llvm.memset.i32") ||
- (FuncName == "llvm.memset.i64") ||
- (FuncName == "llvm.memmove.i32") ||
- (FuncName == "llvm.memmove.i64") ||
- (FuncName == "llva_memcpy") ||
- (FuncName == "llva_memset") ||
- (FuncName == "llva_strncpy") ||
- (FuncName == "llva_invokememcpy") ||
- (FuncName == "llva_invokestrncpy") ||
- (FuncName == "llva_invokememset") ||
- (FuncName == "memcmp")) {
- //
- // Create a call to an accurate bounds check for each string parameter.
- //
- Instruction *InsertPt = CI;
- Value * CastPointer1 = castTo (CI->getOperand(1), Type::UIntTy, InsertPt);
- Value * CastPointer2 = castTo (CI->getOperand(2), Type::UIntTy, InsertPt);
- Value * CastCIOp3 = castTo (CI->getOperand(3), Type::UIntTy, InsertPt);
-
- Instruction *Bop1 = BinaryOperator::create(Instruction::Add, CastPointer1,
- CastCIOp3, "mcadd",InsertPt);
- Instruction *Bop2 = BinaryOperator::create(Instruction::Add, CastPointer2,
- CastCIOp3, "mcadd",InsertPt);
- Instruction *Finalp1 = BinaryOperator::create(Instruction::Sub, Bop1,
- ConstantInt::get (Type::UIntTy, 1), "mcsub",InsertPt);
- Instruction *Finalp2 = BinaryOperator::create(Instruction::Sub, Bop2,
- ConstantInt::get (Type::UIntTy, 1), "mcsub",InsertPt);
-
- Instruction *Length = BinaryOperator::create(Instruction::Sub, CastCIOp3,
- ConstantInt::get (Type::UIntTy, 1), "mclen",InsertPt);
- AddedValues.insert(CastPointer1);
- AddedValues.insert(CastPointer2);
- AddedValues.insert(CastCIOp3);
- AddedValues.insert(Bop1);
- AddedValues.insert(Bop2);
- AddedValues.insert(Finalp1);
- AddedValues.insert(Finalp2);
- AddedValues.insert(Length);
-
- // Create the call to do an accurate bounds check
- if (!insertExactCheck(CI, CI->getOperand(1), Length, InsertPt))
- insertBoundsCheck (CI, CI->getOperand(1), Bop1, InsertPt);
- if (!insertExactCheck(CI, CI->getOperand(2), Length, InsertPt))
- insertBoundsCheck (CI, CI->getOperand(2), Bop2, InsertPt);
-#if 0
- } else if ((FuncName == "llva_load_integer") ||
- (FuncName == "llva_save_integer") ||
- (FuncName == "llva_load_integer_stackp") ||
- (FuncName == "llva_save_integer_stackp") ||
- (FuncName == "llva_push_function1")) {
- //
- // Create a call to an accurate bounds check for the integer state
- // pointer.
- //
- Instruction *InsertPt = CI;
- Value * CastPointer1 = castTo (CI->getOperand(1), Type::UIntTy, InsertPt);
- Value * CastLength = ConstantInt::get (Type::UIntTy, LLVA_INTEGERSTATE_SIZE);
-
- Instruction *Bop1 = BinaryOperator::create(Instruction::Add, CastPointer1,
- CastLength, "mcadd",InsertPt);
- Value *Length = ConstantInt::get (Type::UIntTy, LLVA_INTEGERSTATE_SIZE - 1);
-
- // Create the call to do an accurate bounds check
- if (!insertExactCheck(CI, CI->getOperand(1), Length, InsertPt))
- insertBoundsCheck (CI, CI->getOperand(1), Bop1, InsertPt);
- } else if ((FuncName == "llva_load_icontext") ||
- (FuncName == "llva_save_icontext")) {
- //
- // Perform a check on the interrupt context.
- //
- Instruction *InsertPt = CI;
- insertICCheck (CI->getOperand(1), InsertPt);
-
- //
- // Create a call to an accurate bounds check for the integer state.
- //
- Value * CastPointer1 = castTo (CI->getOperand(2), Type::UIntTy, InsertPt);
- Value * CastLength = ConstantInt::get (Type::UIntTy, LLVA_ICONTEXT_SIZE);
-
- Instruction *Bop1 = BinaryOperator::create(Instruction::Add, CastPointer1,
- CastLength, "mcadd",InsertPt);
- Value *Length = ConstantInt::get (Type::UIntTy, LLVA_ICONTEXT_SIZE - 1);
-
- // Create the call to do an accurate bounds check
- if (!insertExactCheck(CI, CI->getOperand(2), Length, InsertPt))
- insertBoundsCheck (CI, CI->getOperand(1), Bop1, InsertPt);
- } else if ((FuncName == "llva_load_fp") || (FuncName == "llva_save_fp")) {
- //
- // Create a call to an accurate bounds check for the FP state
- // pointer.
- //
- Instruction *InsertPt = CI;
- Value * CastPointer1 = castTo (CI->getOperand(1), Type::UIntTy, InsertPt);
- Value * CastLength = ConstantInt::get (Type::UIntTy, LLVA_FPSTATE_SIZE);
-
- Instruction *Bop1 = BinaryOperator::create(Instruction::Add, CastPointer1,
- CastLength, "mcadd",InsertPt);
- Value *Length = ConstantInt::get (Type::UIntTy, LLVA_FPSTATE_SIZE - 1);
-
- // Create the call to do an accurate bounds check
- if (!insertExactCheck(CI, CI->getOperand(1), Length, InsertPt))
- insertBoundsCheck (CI, CI->getOperand(1), Bop1, InsertPt);
- } else if (FuncName == "llva_push_syscall") {
- //
- // Create a call to an accurate bounds check for the interrupt context
- // pointer.
- //
- Instruction *InsertPt = CI;
- Value * CastPointer1 = castTo (CI->getOperand(2), Type::UIntTy, InsertPt);
- Value * CastLength = ConstantInt::get (Type::UIntTy, LLVA_ICONTEXT_SIZE);
-
- Instruction *Bop1 = BinaryOperator::create(Instruction::Add, CastPointer1,
- CastLength, "mcadd",InsertPt);
- Value *Length = ConstantInt::get (Type::UIntTy, LLVA_ICONTEXT_SIZE - 1);
-
- // Create the call to do an accurate bounds check
- if (!insertExactCheck(CI, CI->getOperand(1), Length, InsertPt))
- insertBoundsCheck (CI, CI->getOperand(1), Bop1, InsertPt);
- } else if ((FuncName == "llva_init_icontext") ||
- (FuncName == "llva_clear_icontext") ||
- (FuncName == "llva_was_privileged") ||
- (FuncName == "llva_icontext_lif") ||
- (FuncName == "llva_ipop_function0") ||
- (FuncName == "llva_ipush_function0") ||
- (FuncName == "llva_ipush_function1") ||
- (FuncName == "llva_ipush_function3") ||
- (FuncName == "llva_ialloca") ||
- (FuncName == "llva_unwind") ||
- (FuncName == "llva_icontext_load_retvalue") ||
- (FuncName == "llva_icontext_save_retvalue") ||
- (FuncName == "llva_get_icontext_stackp") ||
- (FuncName == "llva_set_icontext_stackp") ||
- (FuncName == "llva_iset_privileged")) {
- //
- // Create a call to an accurate bounds check for the interrupt context
- // pointer.
- //
- Instruction *InsertPt = CI;
- insertICCheck (CI->getOperand(1), InsertPt);
-#endif
- }
-#endif
- }
-}
-
-void InsertPoolChecks::simplifyGEPList() {
-#if 0
- std::set<Instruction *> & UnsafeGetElemPtrs = cuaPass->getUnsafeGetElementPtrsFromABC();
- std::map< std::pair<Value*, BasicBlock*>, std::set<Instruction*> > m;
- for (std::set<Instruction *>::iterator ii = UnsafeGetElemPtrs.begin(), ee = UnsafeGetElemPtrs.end();
- ii != ee; ++ii) {
- GetElementPtrInst* GEP = cast<GetElementPtrInst>(*ii);
- m[std::make_pair(GEP->getOperand(0), GEP->getParent())].insert(GEP);
- }
-
- unsigned singletons;
- unsigned multi;
- for (std::map< std::pair<Value*,BasicBlock*>, std::set<Instruction*> >::iterator ii = m.begin(), ee = m.end();
- ii != ee; ++ii) {
- if (ii->second.size() > 1) {
- std::cerr << "##############\n";
- for (std::set<Instruction *>::iterator i = ii->second.begin(), e = ii->second.end();
- i != e; ++i) {
- (*i)->dump();
- }
- std::cerr << "##############\n";
- ++multi;
- } else
- ++singletons;
- }
-
- std::cerr << "Singletons: " << singletons << " Multitons: " << multi << "\n";
-
-#endif
-}
-
-//
-// Function: compatibleGEPs()
-//
-// Description:
-// Determine whether two GEPs address the same memory and have the (save the
-// for last) same arguments.
-//
-// Return value:
-// true - All arguments (except possibly the last) are identical.
-// false - One or more arguments besides the last argument are different.
-//
-static inline bool
-identicalGEPs (GetElementPtrInst * GEP1, GetElementPtrInst * GEP2) {
- if (GEP1->getPointerOperand() != GEP2->getPointerOperand()) return false;
- if (GEP1->getNumOperands() != GEP2->getNumOperands()) return false;
- for (unsigned index = 0; index < GEP1->getNumOperands() - 1; ++index) {
- if (GEP1->getOperand(index) != GEP2->getOperand(index)) {
- return false;
- break;
- }
- }
-
- return true;
-}
-
-bool
-InsertPoolChecks::AggregateGEPs (GetElementPtrInst * MAI,
- std::set<Instruction *> & RelatedGEPs) {
- // Get the set of unsafe GEPs for this instruction's basic block
- std::set<Instruction *> * UnsafeGetElemPtrs = cuaPass->getUnsafeGetElementPtrsFromABC(MAI->getParent());
- if (!UnsafeGetElemPtrs) {
- RelatedGEPs.insert (MAI);
- return true;
- }
-
- // If this GEP has already been deemed safe, then return;
- std::set<Instruction *>::const_iterator iCurrent = UnsafeGetElemPtrs->find(MAI);
- if (iCurrent == UnsafeGetElemPtrs->end()) {
- return true;
- }
-
- // Determine whether the GEP has a constant as its last index.
- // If so, search for all other GEPs that have, save for the last index,
- // identical operands. Then select the two with the higest and lowest
- // indices; we will perform our run-time checks on these.
- std::set<Instruction *>::iterator UGI = UnsafeGetElemPtrs->begin(),
- UGE = UnsafeGetElemPtrs->end();
- Instruction * MinGEP = MAI;
- Instruction * MaxGEP = MAI;
- if (isa<ConstantInt>(MAI->getOperand((MAI->getNumOperands() - 1)))) {
-
- for (;UGI != UGE; ++UGI) {
- Instruction * I = *UGI;
- GetElementPtrInst * GEP = dyn_cast<GetElementPtrInst>(I);
- if (!GEP) continue;
- if (!(isa<ConstantInt>(GEP->getOperand((GEP->getNumOperands() - 1))))) continue;
- if (identicalGEPs (GEP, MAI)) {
- ConstantInt * GEPLastIndex;
- ConstantInt * MinLastIndex;
- ConstantInt * MaxLastIndex;
- GEPLastIndex = dyn_cast<ConstantInt>(GEP->getOperand(GEP->getNumOperands() - 1));
- MinLastIndex = dyn_cast<ConstantInt>(MinGEP->getOperand(MinGEP->getNumOperands() - 1));
- MaxLastIndex = dyn_cast<ConstantInt>(MaxGEP->getOperand(MaxGEP->getNumOperands() - 1));
- if (GEPLastIndex->getSExtValue() < MinLastIndex->getSExtValue()) {
- UnsafeGetElemPtrs->erase (MinGEP);
- MinGEP = GEP;
- }
- if (GEPLastIndex->getSExtValue() > MaxLastIndex->getSExtValue()) {
- UnsafeGetElemPtrs->erase (MaxGEP);
- MaxGEP = GEP;
- }
- }
- }
-
- //
- // Find the first compatible GEP in the basic block.
- //
- Instruction * Ins = MAI->getParent()->getFirstNonPHI();
- GetElementPtrInst * FirstGEP = 0;
- while (!(Ins->isTerminator())) {
- if (FirstGEP = dyn_cast<GetElementPtrInst>(Ins)) {
- if (identicalGEPs (MAI, FirstGEP))
- break;
- }
- Ins = Ins->getNext();
- }
-
- //
- // Move the minimum and maximum GEPs to before the first identical GEP.
- //
- if (FirstGEP != MinGEP) {
- MinGEP->moveBefore (FirstGEP);
- }
- if (FirstGEP != MaxGEP) {
- MaxGEP->moveBefore (FirstGEP);
- }
- }
-
- RelatedGEPs.insert (MinGEP);
- if (MinGEP != MaxGEP) RelatedGEPs.insert (MaxGEP);
-
- return true;
-}
-
-void InsertPoolChecks::handleGetElementPtr(GetElementPtrInst *MAI) {
- // Get the set of unsafe GEP instructions from the array bounds check pass
- // If this instruction is not within that set, then the result of the GEP
- // instruction has been proven safe, and there is no need to insert a check.
- std::set<Instruction *> * UnsafeGetElemPtrs = cuaPass->getUnsafeGetElementPtrsFromABC(MAI->getParent());
- if (!UnsafeGetElemPtrs) return;
- std::set<Instruction *>::const_iterator iCurrent = UnsafeGetElemPtrs->find(MAI);
- if (iCurrent == UnsafeGetElemPtrs->end()) {
-#if 0
- std::cerr << "statically proved safe : Not inserting checks " << *MAI << "\n";
-#endif
- return;
- }
-
-#if 0
- // Find all unsafe GEPs within the basic block that are identical save for
- // their last index
- std::set<Instruction *> RelatedGEPs;
- std::set<Instruction *>::iterator UGI = UnsafeGetElemPtrs->begin(),
- UGE = UnsafeGetElemPtrs->end();
- if (isa<ConstantInt>(MAI->getOperand((MAI->getNumOperands() - 1))))
- for (;UGI != UGE; ++UGI) {
- Instruction * I = *UGI;
- GetElementPtrInst * GEP = dyn_cast<GetElementPtrInst>(I);
- if (!GEP) continue;
- if (GEP->getPointerOperand() != MAI->getPointerOperand()) continue;
- if (GEP->getNumOperands() != MAI->getNumOperands()) continue;
- if (!(isa<ConstantInt>(GEP->getOperand((GEP->getNumOperands() - 1))))) continue;
- bool identical = true;
- for (unsigned index = 0; index < GEP->getNumOperands() - 1; ++index) {
- if (GEP->getOperand(index) != MAI->getOperand(index)) {
- identical = false;
- break;
- }
- }
- if (identical)
- RelatedGEPs.insert (GEP);
- }
-
- std::cerr << "LLVA: RelatedGEP: " << RelatedGEPs.size() << std::endl;
-#endif
-
- if (InsertPoolChecksForArrays) {
- Function *F = MAI->getParent()->getParent();
- GetElementPtrInst *GEP = MAI;
- // Now we need to decide if we need to pass in the alignmnet
- //for the poolcheck
- // if (getDSNodeOffset(GEP->getPointerOperand(), F)) {
- // std::cerr << " we don't handle middle of structs yet\n";
- //assert(!getDSNodeOffset(GEP->getPointerOperand(), F) && " we don't handle middle of structs yet\n");
- // ++MissChecks;
- // continue;
- // }
-
-#ifndef LLVA_KERNEL
- PA::FuncInfo *FI = paPass->getFuncInfoOrClone(*F);
- Instruction *Casted = GEP;
- if (!FI->ValueMap.empty()) {
- assert(FI->ValueMap.count(GEP) && "Instruction not in the value map \n");
- Instruction *temp = dyn_cast<Instruction>(FI->ValueMap[GEP]);
- assert(temp && " Instruction not there in the Value map");
- Casted = temp;
- }
- if (GetElementPtrInst *GEPNew = dyn_cast<GetElementPtrInst>(Casted)) {
- Value *PH = getPoolHandle(GEP, F, *FI);
- if (PH && isa<ConstantPointerNull>(PH)) return;
- if (!PH) {
- Value *PointerOperand = GEPNew->getPointerOperand();
- if (ConstantExpr *cExpr = dyn_cast<ConstantExpr>(PointerOperand)) {
- if (cExpr->getOpcode() == Instruction::Cast)
- PointerOperand = cExpr->getOperand(0);
- }
- if (GlobalVariable *GV = dyn_cast<GlobalVariable>(PointerOperand)) {
- if (const ArrayType *AT = dyn_cast<ArrayType>(GV->getType()->getElementType())) {
- // We need to insert an actual check. It could be a select
- // instruction.
- // First get the size.
- // This only works for one or two dimensional arrays.
- if (GEPNew->getNumOperands() == 2) {
- Value *secOp = GEPNew->getOperand(1);
- if (secOp->getType() != Type::IntTy) {
- secOp = new CastInst(secOp, Type::IntTy,
- secOp->getName()+".ec.casted", Casted);
- }
-
- const Type* csiType = Type::getPrimitiveType(Type::IntTyID);
- std::vector<Value *> args(1,secOp);
- args.push_back(ConstantInt::get(csiType,AT->getNumElements()));
- new CallInst(ExactCheck,args,"", Casted);
- DEBUG(std::cerr << "Inserted exact check call Instruction \n");
- return;
- } else if (GEPNew->getNumOperands() == 3) {
- if (ConstantInt *COP = dyn_cast<ConstantInt>(GEPNew->getOperand(1))) {
- // FIXME: assuming that the first array index is 0
- assert((COP->getZExtValue() == 0) && "non zero array index\n");
- Value * secOp = GEPNew->getOperand(2);
- if (secOp->getType() != Type::IntTy) {
- secOp = new CastInst(secOp, Type::IntTy,
- secOp->getName()+".ec2.casted", Casted);
- }
- std::vector<Value *> args(1,secOp);
- const Type* csiType = Type::getPrimitiveType(Type::IntTyID);
- args.push_back(ConstantInt::get(csiType,AT->getNumElements()));
- new CallInst(ExactCheck, args, "", Casted->getNext());
- return;
- } else {
- // Handle non constant index two dimensional arrays later
- abort();
- }
- } else {
- // Handle Multi dimensional cases later
- DEBUG(std::cerr << "WARNING: Handle multi dimensional globals later\n");
- (*iCurrent)->dump();
- }
- }
- DEBUG(std::cerr << " Global variable ok \n");
- }
-
- // These must be real unknowns and they will be handled anyway
- // std::cerr << " WARNING, DID NOT HANDLE \n";
- // (*iCurrent)->dump();
- return;
- } else {
- if (Casted->getType() != PointerType::get(Type::SByteTy)) {
- Casted = new CastInst(Casted,PointerType::get(Type::SByteTy),
- (Casted)->getName()+".pc.casted",
- (Casted)->getNext());
- }
- std::vector<Value *> args(1, PH);
- args.push_back(Casted);
- // Insert it
- new CallInst(PoolCheck,args, "",Casted->getNext());
- DEBUG(std::cerr << "inserted instrcution \n");
- }
- }
-#else
- //
- // Get the pool handle associated with the pointer operand.
- //
- Value *PH = getPoolHandle(GEP->getPointerOperand(), F);
- GetElementPtrInst *GEPNew = GEP;
- Instruction *Casted = GEP;
-
- DSGraph & TDG = getDSGraph(*F);
- DSNode * Node = TDG.getNodeForValue(GEP).getNode();
-
- DEBUG(std::cerr << "LLVA: addGEPChecks: Pool " << PH << " Node ");
- DEBUG(std::cerr << Node << std::endl);
-
- Value *PointerOperand = GEPNew->getPointerOperand();
- if (ConstantExpr *cExpr = dyn_cast<ConstantExpr>(PointerOperand)) {
- if (cExpr->getOpcode() == Instruction::Cast)
- PointerOperand = cExpr->getOperand(0);
- }
- if (GlobalVariable *GV = dyn_cast<GlobalVariable>(PointerOperand)) {
- if (const ArrayType *AT = dyn_cast<ArrayType>(GV->getType()->getElementType())) {
- // we need to insert an actual check
- // It could be a select instruction
- // First get the size
- // This only works for one or two dimensional arrays
- if (GEPNew->getNumOperands() == 2) {
- Value *secOp = GEPNew->getOperand(1);
-#ifdef LLVA_KERNEL
- //
- // Determine whether the exactcheck() will have constant integer
- // arguments. If so, then we can evaluate them statically and avoid
- // inserting the run-time check.
- //
- if (ConstantInt * Index = dyn_cast<ConstantInt>(secOp)) {
- int index = Index->getSExtValue();
- assert ((index < 0) && "exactcheck will fail at runtime");
- if (index < AT->getNumElements())
- return;
- assert (0 && "exactcheck out of range");
- }
-#endif
- if (secOp->getType() != Type::IntTy) {
- secOp = new CastInst(secOp, Type::IntTy,
- secOp->getName()+".ec3.casted", Casted);
- }
-
- std::vector<Value *> args(1,secOp);
- const Type* csiType = Type::getPrimitiveType(Type::IntTyID);
- args.push_back(ConstantInt::get(csiType,AT->getNumElements()));
- new CallInst(ExactCheck,args,"", Casted);
- // DEBUG(std::cerr << "Inserted exact check call Instruction \n");
- return;
- } else if (GEPNew->getNumOperands() == 3) {
- if (ConstantInt *COP = dyn_cast<ConstantInt>(GEPNew->getOperand(1))) {
- //FIXME assuming that the first array index is 0
- assert((COP->getZExtValue() == 0) && "non zero array index\n");
- Value * secOp = GEPNew->getOperand(2);
-#ifdef LLVA_KERNEL
- //
- // Determine whether the exactcheck() will have constant integer
- // arguments. If so, then we can evaluate them statically and avoid
- // inserting the run-time check.
- //
- if (ConstantInt * Index = dyn_cast<ConstantInt>(secOp)) {
- int index = Index->getSExtValue();
- assert ((index < 0) && "exactcheck will fail at runtime");
- if (index < AT->getNumElements())
- return;
- assert (0 && "exactcheck out of range");
- }
-#endif
- if (secOp->getType() != Type::IntTy) {
- secOp = new CastInst(secOp, Type::IntTy,
- secOp->getName()+".ec4.casted", Casted);
- }
- std::vector<Value *> args(1,secOp);
- const Type* csiType = Type::getPrimitiveType(Type::IntTyID);
- args.push_back(ConstantInt::get(csiType,AT->getNumElements()));
- new CallInst(ExactCheck,args,"", Casted->getNext());
- return;
- } else {
- //Handle non constant index two dimensional arrays later
- abort();
- }
- } else {
- //Handle Multi dimensional cases later
- std::cerr << "WARNING: Handle multi dimensional globals later\n";
- (*iCurrent)->dump();
- ++MissedMultDimArrayChecks;
- }
- DEBUG(std::cerr << " Global variable ok \n");
- }
- }
-
- //
- // We cannot insert an exactcheck(). Insert a pool check.
- //
- //
- if (!PH) {
-#if 0
- std::cerr << "missing a GEP check for" << *MAI << "alloca case?\n";
-#endif
- ++NullChecks;
- if (!PH) ++MissedNullChecks;
- // Don't bother to insert the NULL check unless the user asked
- if (!EnableNullChecks)
- return;
- PH = Constant::getNullValue(PointerType::get(Type::SByteTy));
- } else {
- assert ((isa<GlobalValue>(PH)) && "MetaPool Handle is not a global!");
- }
-
- //
- // If this is a complete node, insert a poolcheck.
- // If this is an icomplete node, insert a poolcheckarray.
- //
- Instruction *InsertPt = Casted->getNext();
- if (Casted->getType() != PointerType::get(Type::SByteTy)) {
- Casted = new CastInst(Casted,PointerType::get(Type::SByteTy),
- (Casted)->getName()+".pc2.casted",InsertPt);
- }
- Instruction *CastedPointerOperand = new CastInst(PointerOperand,
- PointerType::get(Type::SByteTy),
- PointerOperand->getName()+".casted",InsertPt);
- Instruction *CastedPH = new CastInst(PH,
- PointerType::get(Type::SByteTy),
- "ph",InsertPt);
- if (Node->isIncomplete()) {
- std::vector<Value *> args(1, CastedPH);
- args.push_back(CastedPointerOperand);
- args.push_back(Casted);
- CallInst(PoolCheckArray,args, "",InsertPt);
- } else {
- std::vector<Value *> args(1, CastedPH);
- args.push_back(Casted);
- new CallInst(PoolCheck,args, "",InsertPt);
- }
-#endif
- } else {
- // Insert accurate bounds checks for arrays (as opposed to poolchecks)
-
- //
- // Attempt to insert a standard exactcheck() call for the GEP.
- //
- if (insertExactCheck (MAI))
- return;
-
- //Exact poolchecks
- if (const PointerType *PT = dyn_cast<PointerType>(MAI->getPointerOperand()->getType())) {
-#if 0
- if (const StructType *ST = dyn_cast<StructType>(PT->getElementType())) {
-#else
- const StructType *ST = dyn_cast<StructType>(PT->getElementType());
- if (0) {
-#endif
- //It is a struct type with pointers
- //for each pointer with struct typ
- //we need to watchg out for arrays inside structs
- if (ConstantInt *COP = dyn_cast<ConstantInt>(MAI->getOperand(1))) {
- //FIXME assuming that the first index is safe
- //assert((COP->getRawValue() == 0) && "non zero array index\n");
- bool allconstant = true;
- for (unsigned i = 2; i < MAI->getNumOperands(); ++i) {
- if (!isa<Constant>(MAI->getOperand(i))) {
- allconstant = false;
- break;
- }
- }
- if (!allconstant) {
- if (MAI->getNumOperands() == 4) {
- if (ConstantInt *COPi = dyn_cast<ConstantInt>(MAI->getOperand(2))) {
- const Type *stel = ST->getElementType(COPi->getZExtValue());
- if (const ArrayType *elAT = dyn_cast<ArrayType>(stel)) {
- //Need to factor this in to separate method!!!
- Value * secOp = MAI->getOperand(3);
- Value *indexTypeSize = ConstantInt::get(Type::UIntTy, TD->getTypeSize(secOp->getType()));
-#ifdef LLVA_KERNEL
- //
- // Determine whether the exactcheck() will have constant integer
- // arguments. If so, then we can evaluate them statically and avoid
- // inserting the run-time check.
- //
- if (ConstantInt * Index = dyn_cast<ConstantInt>(secOp)) {
- int index = Index->getSExtValue();
- assert ((index < 0) && "exactcheck will fail at runtime");
- if (index < TD->getTypeSize(elAT))
- return;
- assert (0 && "exactcheck out of range");
- }
-#endif
- if (secOp->getType() != Type::IntTy) {
- secOp = new CastInst(secOp, Type::IntTy,
- secOp->getName()+".casted", MAI);
- }
- // secOp = BinaryOperator::create(Instruction::Mul, indexTypeSize, secOp,"indextmp", MAI);
- std::vector<Value *> args(1,secOp);
- Value *AllocSize =
- ConstantInt::get(Type::IntTy, TD->getTypeSize(elAT));
- /*
- if (AI->isArrayAllocation())
- AllocSize = BinaryOperator::create(Instruction::Mul,
- AllocSize,
- AI->getOperand(0), "sizetmp", MAI);
- */
- // args.push_back(ConstantInt::get(csiType,elAT->getNumElements()));
- args.push_back(AllocSize);
- new CallInst(ExactCheck,args,"",MAI);
-
- } else {
- //non array, non constant value
- abort();
- }
- } else {
- // non-constant value, not possible
- abort();
- }
- } else {
-#if 0
- //FIXME this is a less precise check than possible
- // std::cerr << "WARNING : did not handle array within a struct precisely, num operands != 4\n";
- Instruction *InsertPt = MAI->getNext();
- Type *VoidPtrType = PointerType::get(Type::SByteTy);
- Value *MAIPSbyte = new CastInst(MAI->getPointerOperand(),
- VoidPtrType,
- MAI->getPointerOperand()->getName()+".casted",InsertPt);
-
- Value *MAISbyte = new CastInst(MAI,
- VoidPtrType,
- MAI->getName()+".casted",InsertPt);
-
- std::vector<Value *> args(1,MAIPSbyte);
- args.push_back(MAISbyte);
- Value *AllocSize =
- ConstantInt::get(Type::UIntTy, TD->getTypeSize(ST));
- args.push_back(AllocSize);
- new CallInst(ExactCheck2,args,"",InsertPt);
-#endif
- }
- } else {
- std::cerr << "Not all args constant: " << *MAI << std::endl;
- }
- } else {
- std::cerr << "HandleLikeArray: " << *MAI << std::endl;
- goto HandleThisLikeArray;
- }
- } else {
- HandleThisLikeArray:
- if (AllocaInst *AI = dyn_cast<AllocaInst>(MAI->getPointerOperand())) {
- //we can put an exact check here
- if (1 || (MAI->getNumOperands() == 3)) {
- if (ConstantInt *COP = dyn_cast<ConstantInt>(MAI->getOperand(1))) {
- //FIXME assuming that the first array index is 0
-#if 0
- assert((COP->getZExtValue() == 0) && "non zero array index\n");
-#else
- if (COP->getZExtValue() == 0) {
-#endif
- Value * secOp = MAI->getOperand(2);
- Value *indexTypeSize = ConstantInt::get(Type::UIntTy, TD->getTypeSize(secOp->getType()));
-#ifdef LLVA_KERNEL
- //
- // Determine whether the exactcheck() will have constant integer
- // arguments. If so, then we can evaluate them statically and avoid
- // inserting the run-time check.
- //
- if (!(AI->isArrayAllocation()))
- if (ConstantInt * Index = dyn_cast<ConstantInt>(secOp)) {
- int index = Index->getSExtValue();
- if ((index > 0) && (index < TD->getTypeSize(AI->getAllocatedType())))
- return;
- }
-#endif
- //Convert everything to bytes
- if (secOp->getType() != Type::IntTy) {
- secOp = new CastInst(secOp, Type::IntTy, secOp->getName()+".casted",
- MAI);
- }
- // secOp = BinaryOperator::create(Instruction::Mul, indexTypeSize, secOp,"indextmp",MAI);
- std::vector<Value *> args(1,secOp);
- Value *AllocSize =
- ConstantInt::get(Type::IntTy, TD->getTypeSize(AI->getAllocatedType()));
-
- if (AI->isArrayAllocation())
- AllocSize = BinaryOperator::create(Instruction::Mul,
- AllocSize,
- AI->getOperand(0), "sizetmp", MAI);
-
- args.push_back(AllocSize);
- CallInst *newCI = new CallInst(ExactCheck,args,"", MAI);
- } else {
- std::cerr << "COP not zero: " << *MAI << std::endl;
- }
- } else {
- std::cerr << "Bad COP: " << *MAI << std::endl;
- }
- } else {
- std::cerr << " num operands != 3: " << *MAI << std::endl;
- abort();
- }
- } else {
- // Now check if the GEP is inside a loop with monotonically increasing
- //loop bounds
- //We use the LoopInfo Pass this
- Loop *L = LI->getLoopFor(MAI->getParent());
- bool monotonicOpt = false;
- if (L && (MAI->getNumOperands() == 2)) {
- bool HasConstantItCount = isa<SCEVConstant>(scevPass->getIterationCount(L));
- Value *vIndex = MAI->getOperand(1);
- if (Instruction *Index = dyn_cast<Instruction>(vIndex)) {
- //If it is not an instruction then it must already be loop invariant
- if (L->isLoopInvariant(MAI->getPointerOperand())) {
- SCEVHandle SH = scevPass->getSCEV(Index);
- if (SH->hasComputableLoopEvolution(L) || // Varies predictably
- HasConstantItCount) {
- if (SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(SH))
- if (AR->isAffine()) {
- SCEVHandle EntryValue = AR->getStart();
- // EntryValue->getValueRange().dump();
- // Index->dump();
- SCEVHandle ExitValue = scevPass->getSCEVAtScope(Index, L->getParentLoop());
- BasicBlock *Preheader = L->getLoopPreheader();
- if ((Preheader) &&
- (!isa<SCEVCouldNotCompute>(ExitValue)) ){
- SCEVExpander Rewriter(*scevPass, *LI);
- Instruction *ptIns = Preheader->getTerminator();
- Value *NewVal = Rewriter.expandCodeFor(ExitValue, ptIns,
- Index->getType());
- // NewVal->dump();
- if (!isa<SCEVCouldNotCompute>(EntryValue)) {
- Value *NewVal2 = Rewriter.expandCodeFor(EntryValue, ptIns,
- Index->getType());
- // NewVal2->dump();
- //Inserted the values now insert GEPs and add checks
- std::vector<Value *> gepargs1(1,NewVal);
- GetElementPtrInst *GEPUpper =
- new GetElementPtrInst(MAI->getPointerOperand(), gepargs1, MAI->getName()+"upbc", ptIns);
- insertBoundsCheck (MAI, GEPUpper->getPointerOperand(), GEPUpper, ptIns);
- std::vector<Value *> gepargs2(1,NewVal2);
- GetElementPtrInst *GEPLower =
- new GetElementPtrInst(MAI->getPointerOperand(), gepargs2, MAI->getName()+"lobc", ptIns);
- insertBoundsCheck (MAI, GEPLower->getPointerOperand(), GEPLower, ptIns);
- monotonicOpt = true;
- ++MonotonicOpts;
- }
- }
- }
- }
- }
- }
- }
- if (!monotonicOpt) {
- //
- // Insert a bounds check and use its return value in all subsequent
- // uses.
- //
- Instruction *nextIns = MAI->getNext();
- insertBoundsCheck (MAI, MAI->getPointerOperand(), MAI, nextIns);
- }
- }
- }
- } else {
- std::cerr << "GEP does not have pointer type arg" << *MAI << std::endl;
- abort();
- }
- }
-}
-
- void InsertPoolChecks::addGetActualValue(SetCondInst *SCI, unsigned operand) {
- //we know that the operand is a pointer type
- Value *op = SCI->getOperand(operand);
- Function *F = SCI->getParent()->getParent();
-#ifndef LLVA_KERNEL
-#ifdef NOEQUIV
- if (!equivPass->ContainsDSGraphFor(*F)) {
- //some times the ECGraphs doesnt contain F
- //for newly created cloned functions
- PA::FuncInfo *FI = paPass->getFuncInfoOrClone(*F);
- op = FI->MapValueToOriginal(op);
- if (!op) return; //abort();
- }
-#endif
-#endif
- Function *Fnew = F;
- Value *PH = 0;
- if (Argument *arg = dyn_cast<Argument>(op)) {
- Fnew = arg->getParent();
- PH = getPoolHandle(op, Fnew);
- } else if (Instruction *Inst = dyn_cast<Instruction>(op)) {
- Fnew = Inst->getParent()->getParent();
- PH = getPoolHandle(op, Fnew);
- } else if (isa<Constant>(op)) {
- return;
- // abort();
- } else if (!isa<ConstantPointerNull>(op)) {
- //has to be a global
- abort();
- }
- op = SCI->getOperand(operand);
- if (!isa<ConstantPointerNull>(op)) {
- if (PH) {
- if (1) { //HACK fixed
- Type *VoidPtrType = PointerType::get(Type::SByteTy);
- Value *PHVptr = new CastInst(PH, VoidPtrType,
- PH->getName()+".casted", SCI);
- Value *OpVptr = op;
- if (op->getType() != VoidPtrType)
- OpVptr = new CastInst(op, VoidPtrType,
- op->getName()+".casted", SCI);
-
- std::vector<Value *> args = make_vector(PHVptr, OpVptr,0);
- CallInst *CI = new CallInst(GetActualValue, args,"getval", SCI);
- CastInst *CastBack = new CastInst(CI, op->getType(), op->getName()+".castback",SCI);
- SCI->setOperand(operand, CastBack);
+ Module::global_iterator GI = M.global_begin(), GE = M.global_end();
+ for ( ; GI != GE; ++GI) {
+ if (GlobalVariable *GV = dyn_cast<GlobalVariable>(GI)) {
+ Type *VoidPtrType = PointerType::get(Type::SByteTy);
+ Type *PoolDescType = ArrayType::get(VoidPtrType, 50);
+ Type *PoolDescPtrTy = PointerType::get(PoolDescType);
+ if (GV->getType() != PoolDescPtrTy) {
+ DSGraph &G = equivPass->getGlobalsGraph();
+ DSNode *DSN = G.getNodeForValue(GV).getNode();
+ if ((isa<ArrayType>(GV->getType()->getElementType())) || DSN->isNodeCompletelyFolded()) {
+ Value * AllocSize;
+ const Type* csiType = Type::getPrimitiveType(Type::UIntTyID);
+ if (const ArrayType *AT = dyn_cast<ArrayType>(GV->getType()->getElementType())) {
+ //std::cerr << "found global \n";
+ AllocSize = ConstantInt::get(csiType,
+ (AT->getNumElements() * TD->getTypeSize(AT->getElementType())));
+ } else {
+ AllocSize = ConstantInt::get(csiType, TD->getTypeSize(GV->getType()));
+ }
+ Function *PoolRegister = paPass->PoolRegister;
+ BasicBlock::iterator InsertPt = MainFunc->getEntryBlock().begin();
+ //skip the calls to poolinit
+ while ((isa<CallInst>(InsertPt)) || isa<CastInst>(InsertPt) || isa<AllocaInst>(InsertPt) || isa<BinaryOperator>(InsertPt)) ++InsertPt;
+
+ std::map<const DSNode *, Value *>::iterator I = paPass->GlobalNodes.find(DSN);
+ if (I != paPass->GlobalNodes.end()) {
+ Value *PH = I->second;
+ Instruction *GVCasted = new CastInst(GV,
+ VoidPtrType, GV->getName()+"casted",InsertPt);
+ new CallInst(PoolRegister,
+ make_vector(PH, AllocSize, GVCasted, 0),
+ "", InsertPt);
+ } else {
+ std::cerr << "pool descriptor not present \n ";
+ abort();
+ }
+ }
}
- } else {
- //It shouldn't work if PH is not null
}
}
}
-
-void InsertPoolChecks::TransformFunction (Function & F) {
-#ifndef LLVA_KERNEL
- PA::FuncInfo * PAFI = paPass->getFuncInfoOrClone(F);
- if (PAFI->Clone && PAFI->Clone != &F) {
- //no need to transform
- return;
- }
-#endif
- inst_iterator I = inst_begin(F);
- while (I != inst_end(F)) {
- Instruction *iLocal = &*I;
- if (SetCondInst *SCI = dyn_cast<SetCondInst>(iLocal)) {
- //If it is neq, eq,
- if ((SCI->getOpcode() == BinaryOperator::SetEQ) || (SCI->getOpcode() == BinaryOperator::SetNE)) {
- //for all the pointer operands replace them by the getactualvalue
- assert((SCI->getNumOperands() == 2) && "nmber of operands for SCI different from 2 ");
- if (isa<PointerType>(SCI->getOperand(0)->getType())) {
- //we need to insert a call to getactualvalue
- //First get the poolhandle for the pointer
- // TODO: We don't have a working getactualvalue(), so don't waste
- // time calling it.
-#if 0
- if ((!isa<ConstantPointerNull>(SCI->getOperand(0))) && (!isa<ConstantPointerNull>(SCI->getOperand(1)))) {
- addGetActualValue(SCI, 0);
- addGetActualValue(SCI, 1);
- }
#endif
- }
- }
- } else if (isa<CastInst>(iLocal)) {
- //Some times the getelementptr is an argument of cast instruction
- // and we don't want to miss a run-time check there
- if (isa<GetElementPtrInst>(iLocal->getOperand(0))) {
- iLocal = cast<Instruction>(iLocal->getOperand(0));
- }
- } //
- // we need to handle
- // alloca instructions
- // getelement ptrs
- // load store checks
- if (isa<GetElementPtrInst>(iLocal)) {
- GetElementPtrInst *MAI = cast<GetElementPtrInst>(iLocal);
- ++I;
- std::set<Instruction *> CheckSet;
- AggregateGEPs (MAI, CheckSet);
- for (std::set<Instruction *>::iterator GEP = CheckSet.begin();
- GEP != CheckSet.end(); ++GEP) {
- Instruction * I = *GEP;
- GetElementPtrInst * GEPI = dyn_cast<GetElementPtrInst>(I);
- handleGetElementPtr(GEPI);
- }
- continue;
- } else if (AllocaInst *AI = dyn_cast<AllocaInst>(iLocal)) {
- AllocaInst * AIOrig = AI;
- if (!DisableStackChecks) {
-#ifndef LLVA_KERNEL
-#ifdef NOEQUIV
- if (!equivPass->ContainsDSGraphFor(F)) {
- //some times the ECGraphs doesnt contain F
- //for newly created cloned functions
- PA::FuncInfo *FI = paPass->getFuncInfoOrClone(F);
- Value *temp = FI->MapValueToOriginal(AI);
- if (temp)
- AIOrig = dyn_cast<AllocaInst>(temp);
- else
- continue;
- assert(AIOrig && " Instruction not in value map (clone)\n");
- }
-#endif
-#endif
- ++I;
- registerAllocaInst(AI, AIOrig);
- continue;
- }
- } else if (CallInst *CI = dyn_cast<CallInst>(iLocal)) {
- ++I;
- handleCallInst(CI);
- continue;
- }
-
- //
- // Move to the next instruction.
- //
- ++I;
- }
+void InsertPoolChecks::addPoolChecks(Module &M) {
+ if (!DisableGEPChecks) addGetElementPtrChecks(M);
+ if (!DisableLSChecks) addLoadStoreChecks(M);
}
-void InsertPoolChecks::registerAllocaInst(AllocaInst *AI, AllocaInst *AIOrig) {
- //
- // Get the pool handle for the node that this contributes to...
- //
- Function *FOrig = AIOrig->getParent()->getParent();
- DSNode *Node = getDSNode(AIOrig, FOrig);
- if (!Node) return;
- assert ((Node->isAllocaNode()) && "DSNode for alloca is missing stack flag!");
-
- //
- // Only register the stack allocation if it may be the subject of a run-time
- // check. This can only occur when the object is used like an array because:
- // 1) GEP checks are only done when accessing arrays.
- // 2) Load/Store checks are only done on collapsed nodes (which appear to be
- // used like arrays).
- //
- if (!(Node->isArray()))
- return;
-
- //
- // Determine if any use (direct or indirect) escapes this function. If not,
- // then none of the checks will consult the MetaPool, and we can forego
- // registering the alloca.
- //
- bool MustRegisterAlloca = false;
- std::vector<Value *> AllocaWorkList;
- AllocaWorkList.push_back (AI);
- while ((!MustRegisterAlloca) && (AllocaWorkList.size())) {
- Value * V = AllocaWorkList.back();
- AllocaWorkList.pop_back();
- Value::use_iterator UI = V->use_begin();
- for (; UI != V->use_end(); ++UI) {
- // We cannot handle PHI nodes or Select instructions
- if (isa<PHINode>(UI) || isa<SelectInst>(UI)) {
- MustRegisterAlloca = true;
- continue;
- }
-
- // The pointer escapes if it's stored to memory somewhere.
- StoreInst * SI;
- if ((SI = dyn_cast<StoreInst>(UI)) && (SI->getOperand(0) == V)) {
- MustRegisterAlloca = true;
- continue;
- }
-
- // GEP instructions are okay, but need to be added to the worklist
- if (isa<GetElementPtrInst>(UI)) {
- AllocaWorkList.push_back (*UI);
- continue;
- }
-
- // Cast instructions are okay as long as they cast to another pointer
- // type
- if (CastInst * CI = dyn_cast<CastInst>(UI)) {
- if (isa<PointerType>(CI->getType())) {
- AllocaWorkList.push_back (*UI);
- continue;
- } else {
- MustRegisterAlloca = true;
- continue;
- }
- }
-
- if (ConstantExpr *cExpr = dyn_cast<ConstantExpr>(UI)) {
- if (cExpr->getOpcode() == Instruction::Cast) {
- AllocaWorkList.push_back (*UI);
- continue;
- } else {
- MustRegisterAlloca = true;
- continue;
- }
- }
-
- CallInst * CI1;
- if (CI1 = dyn_cast<CallInst>(UI)) {
- if (!(CI1->getCalledFunction())) {
- MustRegisterAlloca = true;
- continue;
- }
-
- std::string FuncName = CI1->getCalledFunction()->getName();
- if (FuncName == "exactcheck3") {
- AllocaWorkList.push_back (*UI);
- continue;
- } else if ((FuncName == "llvm.memcpy.i32") ||
- (FuncName == "llvm.memcpy.i64") ||
- (FuncName == "llvm.memset.i32") ||
- (FuncName == "llvm.memset.i64") ||
- (FuncName == "llvm.memmove.i32") ||
- (FuncName == "llvm.memmove.i64") ||
- (FuncName == "llva_memcpy") ||
- (FuncName == "llva_memset") ||
- (FuncName == "llva_strncpy") ||
- (FuncName == "llva_invokememcpy") ||
- (FuncName == "llva_invokestrncpy") ||
- (FuncName == "llva_invokememset") ||
- (FuncName == "memcmp")) {
- continue;
- } else {
- MustRegisterAlloca = true;
- continue;
- }
- }
- }
- }
-
- if (!MustRegisterAlloca) {
- ++SavedRegAllocs;
- return;
- }
-
- //
- // Insert the alloca registration.
- //
- Value *PH = getPoolHandle(AIOrig, FOrig);
- if (PH == 0 || isa<ConstantPointerNull>(PH)) return;
-
- Value *AllocSize =
- ConstantInt::get(Type::UIntTy, TD->getTypeSize(AI->getAllocatedType()));
-
- if (AI->isArrayAllocation())
- AllocSize = BinaryOperator::create(Instruction::Mul, AllocSize,
- AI->getOperand(0), "sizetmp", AI);
-
- // Insert object registration at the end of allocas.
- Instruction *iptI = AI->getNext();
- if (AI->getParent() == (&(AI->getParent()->getParent()->getEntryBlock()))) {
- BasicBlock::iterator InsertPt = AI->getParent()->begin();
- while (&(*(InsertPt)) != AI)
- ++InsertPt;
- while (isa<AllocaInst>(InsertPt))
- ++InsertPt;
- iptI = InsertPt;
- }
-
- //
- // Insert a call to register the object.
- //
- Instruction *Casted = new CastInst(AI, PointerType::get(Type::SByteTy),
- AI->getName()+".casted", iptI);
- Value *CastedPH = new CastInst(PH,
- PointerType::get(Type::SByteTy),
- "allocph",Casted);
- new CallInst(StackRegister,
- make_vector(CastedPH, Casted, AllocSize,0),
- "", iptI);
-
- //
- // Insert a call to unregister the object whenever the function can exit.
- //
- for (Function::iterator BB = AI->getParent()->getParent()->begin();
- BB != AI->getParent()->getParent()->end();
- ++BB) {
- iptI = BB->getTerminator();
- if (isa<ReturnInst>(iptI) || isa<UnwindInst>(iptI))
- new CallInst(StackFree,
- make_vector(CastedPH, Casted, 0),
- "", iptI);
- }
-
- // Update statistics
- ++StackRegisters;
-}
-
-//
-// Method: insertAlignmentCheck()
-//
-// Description:
-// Insert an alignment check for the specified value.
-//
-void
-InsertPoolChecks::insertAlignmentCheck (LoadInst * LI) {
- // Get the function containing the load instruction
- Function * F = LI->getParent()->getParent();
-
- // Get the DSNode for the result of the load instruction. If it is type
- // unknown, then no alignment check is needed.
- DSNode * LoadResultNode = getDSNode (LI,F);
- if (!(LoadResultNode && (!(LoadResultNode->isNodeCompletelyFolded())))) {
- return;
- }
-
- //
- // Get the pool handle for the node.
- //
- Value *PH = getPoolHandle(LI, F);
- if (!PH) return;
-
- //
- // If the node is incomplete or unknown, then only perform the check if
- // checks to incomplete or unknown are allowed.
- //
- Function * ThePoolCheckFunction = PoolCheckAlign;
- if ((LoadResultNode->isUnknownNode()) || (LoadResultNode->isIncomplete())) {
- if (EnableUnknownChecks) {
- ThePoolCheckFunction = PoolCheckAlignUI;
- } else {
- ++MissedIncompleteChecks;
- return;
- }
- }
-
- //
- // A check is needed. Scan through the links of the DSNode of the load's
- // pointer operand; we need to determine the offset for the alignment check.
- //
- DSNode * Node = getDSNode (LI->getPointerOperand(), F);
- if (!Node) return;
- for (unsigned i = 0 ; i < Node->getNumLinks(); ++i) {
- DSNodeHandle & LinkNode = Node->getLink(i);
- if (LinkNode.getNode() == LoadResultNode) {
- // Insertion point for this check is *after* the load.
- Instruction * InsertPt = LI->getNext();
-
- // Create instructions to cast the checked pointer and the checked pool
- // into sbyte pointers.
- Value *CastVI = castTo (LI, PointerType::get(Type::SByteTy), InsertPt);
- Value *CastPHI = castTo (PH, PointerType::get(Type::SByteTy), InsertPt);
-
- // Create the call to poolcheck
- std::vector<Value *> args(1,CastPHI);
- args.push_back(CastVI);
- args.push_back (ConstantInt::get(Type::UIntTy, LinkNode.getOffset()));
- new CallInst (PoolCheckAlign,args, "", InsertPt);
-
- // Update the statistics
- ++AlignLSChecks;
-
- break;
- }
- }
-}
-
#ifdef LLVA_KERNEL
//
// Method: addLSChecks()
@@ -3377,111 +187,94 @@
// Insert a poolcheck() into the code for a load or store instruction.
//
void InsertPoolChecks::addLSChecks(Value *V, Instruction *I, Function *F) {
- // Get the DSNode for the pointer to check
- DSNode * Node = getDSNode (V,F);
-
- //
- // Do not perform any checks if there is no DSNode, if the node is not folded,
- // or if the node is incomplete.
- //
- if (!(Node && Node->isNodeCompletelyFolded()))
- return;
-
- //
- // If the node is not registered, don't bother to check it.
- //
- if (!(isNodeRegistered (Node)))
- return;
-
- //
- // We will perform checks on incomplete or unknown nodes, but we must accept
- // the possibility that the object will not be found.
- //
- Function * ThePoolCheckFunction = PoolCheck;
- if ((Node->isUnknownNode()) || (Node->isIncomplete())) {
- if (EnableUnknownChecks) {
- ThePoolCheckFunction = PoolCheckUI;
- } else {
- ++MissedIncompleteChecks;
- return;
+ DSGraph & TDG = TDPass->getDSGraph(*F);
+ DSNode * Node = TDG.getNodeForValue(V).getNode();
+
+ if (Node && Node->isNodeCompletelyFolded()) {
+ if (!EnableIncompleteChecks) {
+ if (Node->isIncomplete()) {
+ ++MissedIncompleteChecks;
+ return;
+ }
}
+ // Get the pool handle associated with this pointer. If there is no pool
+ // handle, use a NULL pointer value and let the runtime deal with it.
+ Value *PH = getPoolHandle(V, F);
+#ifdef DEBUG
+std::cerr << "LLVA: addLSChecks: Pool " << PH << " Node " << Node << std::endl;
+#endif
+ // FIXME: We cannot handle checks to global or stack positions right now.
+ if ((!PH) || (Node->isAllocaNode()) || (Node->isGlobalNode())) {
+ ++NullChecks;
+ if (!PH) ++MissedNullChecks;
+ if (Node->isAllocaNode()) ++MissedStackChecks;
+ if (Node->isGlobalNode()) ++MissedGlobalChecks;
+
+ // Don't bother to insert the NULL check unless the user asked
+ if (!EnableNullChecks)
+ return;
+ PH = Constant::getNullValue(PointerType::get(Type::SByteTy));
+ } else {
+ //
+ // Only add the pool check if the pool is a global value or it
+ // belongs to the same basic block.
+ //
+ if (isa<GlobalValue>(PH)) {
+ ++FullChecks;
+ } else if (isa<Instruction>(PH)) {
+ Instruction * IPH = (Instruction *)(PH);
+ if (IPH->getParent() == I->getParent()) {
+ //
+ // If the instructions belong to the same basic block, ensure that
+ // the pool dominates the load/store.
+ //
+ Instruction * IP = IPH;
+ for (IP=IPH; (IP->isTerminator()) || (IP == I); IP=IP->getNext()) {
+ ;
+ }
+ if (IP == I)
+ ++FullChecks;
+ else {
+ ++MissChecks;
+ return;
+ }
+ } else {
+ ++MissChecks;
+ return;
+ }
+ } else {
+ ++MissChecks;
+ return;
+ }
+ }
+ // Create instructions to cast the checked pointer and the checked pool
+ // into sbyte pointers.
+ CastInst *CastVI =
+ new CastInst(V,
+ PointerType::get(Type::SByteTy), "node.lscasted", I);
+ CastInst *CastPHI =
+ new CastInst(PH,
+ PointerType::get(Type::SByteTy), "poolhandle.lscasted", I);
+
+ // Create the call to poolcheck
+ std::vector<Value *> args(1,CastPHI);
+ args.push_back(CastVI);
+ new CallInst(PoolCheck,args,"", I);
}
-
- //
- // This may be a load instruction that loads a pointer that:
- // 1) Points to a type known pool, and
- // 2) Loaded from a type unknown pool
- //
- // If this is the case, we need to perform an alignment check on the result
- // of the load. Do that here.
- //
- if (LoadInst * LI = dyn_cast<LoadInst>(I)) {
- insertAlignmentCheck (LI);
- }
-
- //
- // Do not perform a load/store check if the pointer used for this operation
- // has already been checked.
- //
- if (findCheckedPointer(V)) {
- ++SavedPoolChecks;
- return;
- }
-
- // Get the pool handle associated with this pointer. If there is no pool
- // handle, use a NULL pointer value and let the runtime deal with it.
- Value *PH = getPoolHandle(V, F);
-
- if (!PH) {
- // Update the number of poolchecks that won't do anything
- ++NullChecks;
-
- // Update the stats on why there will be no check
- ++MissedNullChecks;
-
- // Don't bother to insert the NULL check unless the user requested it
- if (!EnableNullChecks)
- return;
- PH = Constant::getNullValue(PointerType::get(Type::SByteTy));
- } else {
- // This will be a full check; update the stats.
- assert (isa<GlobalValue>(PH));
- ++FullChecks;
- }
-
- // Create instructions to cast the checked pointer and the checked pool
- // into sbyte pointers.
- Value *CastVI = castTo (V, PointerType::get(Type::SByteTy), I);
- Value *CastPHI = castTo (PH, PointerType::get(Type::SByteTy), I);
-
- // Create the call to poolcheck
- std::vector<Value *> args(1,CastPHI);
- args.push_back(CastVI);
- new CallInst (ThePoolCheckFunction ,args, "", I);
}
-void InsertPoolChecks::addLoadStoreChecks (Function & FR) {
- Function *F = &FR;
- for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {
- if (LoadInst *LI = dyn_cast<LoadInst>(&*I)) {
- Value *P = LI->getPointerOperand();
- addLSChecks(P, LI, F);
- } else if (StoreInst *SI = dyn_cast<StoreInst>(&*I)) {
- Value *P = SI->getPointerOperand();
- addLSChecks(P, SI, F);
- } else if (CallInst * CI = dyn_cast<CallInst>(&*I)) {
- if (Function * CalledFunc = CI->getCalledFunction()) {
- if ((CalledFunc->getName() == "llva_atomic_compare_and_swap") ||
- (CalledFunc->getName() == "llva_atomic_cas_lw") ||
- (CalledFunc->getName() == "llva_atomic_cas_h") ||
- (CalledFunc->getName() == "llva_atomic_cas_b") ||
- (CalledFunc->getName() == "llva_atomic_fetch_add_store") ||
- (CalledFunc->getName() == "llva_atomic_and") ||
- (CalledFunc->getName() == "llva_atomic_or")) {
- Value * P = CI->getOperand(1);
- addLSChecks (P, CI, F);
- }
- }
+void InsertPoolChecks::addLoadStoreChecks(Module &M){
+ Module::iterator mI = M.begin(), mE = M.end();
+ for ( ; mI != mE; ++mI) {
+ Function *F = mI;
+ for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {
+ if (LoadInst *LI = dyn_cast<LoadInst>(&*I)) {
+ Value *P = LI->getPointerOperand();
+ addLSChecks(P, LI, F);
+ } else if (StoreInst *SI = dyn_cast<StoreInst>(&*I)) {
+ Value *P = SI->getPointerOperand();
+ addLSChecks(P, SI, F);
+ }
}
}
}
@@ -3543,94 +336,480 @@
}
}
-void InsertPoolChecks::addLoadStoreChecks(Function & Func){
- Function *F = &Func;
- //here we check that we only do this on original functions
- //and not the cloned functions, the cloned functions may not have the
- //DSG
- bool isClonedFunc = false;
- if (paPass->getFuncInfo(*F))
- isClonedFunc = false;
- else
- isClonedFunc = true;
- Function *Forig = F;
- PA::FuncInfo *FI = paPass->getFuncInfoOrClone(*F);
- if (isClonedFunc) {
- Forig = paPass->getOrigFunctionFromClone(F);
- }
- //we got the original function
- for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {
- if (LoadInst *LI = dyn_cast<LoadInst>(&*I)) {
-//we need to get the LI from the original function
-Value *P = LI->getPointerOperand();
-if (isClonedFunc) {
- assert(FI->NewToOldValueMap.count(LI) && " not in the value map \n");
- const LoadInst *temp = dyn_cast<LoadInst>(FI->NewToOldValueMap[LI]);
- assert(temp && " Instruction not there in the NewToOldValue map");
- const Value *Ptr = temp->getPointerOperand();
- addLSChecks(P, Ptr, LI, Forig);
-} else {
- addLSChecks(P, P, LI, Forig);
-}
- } else if (StoreInst *SI = dyn_cast<StoreInst>(&*I)) {
-Value *P = SI->getPointerOperand();
-if (isClonedFunc) {
- assert(FI->NewToOldValueMap.count(SI) && " not in the value map \n");
- const StoreInst *temp = dyn_cast<StoreInst>(FI->NewToOldValueMap[SI]);
- assert(temp && " Instruction not there in the NewToOldValue map");
- const Value *Ptr = temp->getPointerOperand();
- addLSChecks(P, Ptr, SI, Forig);
-} else {
- addLSChecks(P, P, SI, Forig);
-}
- } else if (CallInst *CI = dyn_cast<CallInst>(&*I)) {
-Value *FunctionOp = CI->getOperand(0);
-if (!isa<Function>(FunctionOp)) {
- if (isClonedFunc) {
- assert(FI->NewToOldValueMap.count(CI) && " not in the value map \n");
- const CallInst *temp = dyn_cast<CallInst>(FI->NewToOldValueMap[CI]);
- assert(temp && " Instruction not there in the NewToOldValue map");
- const Value* FunctionOp1 = temp->getOperand(0);
- addLSChecks(FunctionOp, FunctionOp1, CI, Forig);
- } else {
- addLSChecks(FunctionOp, FunctionOp, CI, Forig);
- }
-}
- }
+void InsertPoolChecks::addLoadStoreChecks(Module &M){
+ Module::iterator mI = M.begin(), mE = M.end();
+ for ( ; mI != mE; ++mI) {
+ Function *F = mI;
+ //here we check that we only do this on original functions
+ //and not the cloned functions, the cloned functions may not have the
+ //DSG
+ bool isClonedFunc = false;
+ if (paPass->getFuncInfo(*F))
+ isClonedFunc = false;
+ else
+ isClonedFunc = true;
+ Function *Forig = F;
+ PA::FuncInfo *FI = paPass->getFuncInfoOrClone(*F);
+ if (isClonedFunc) {
+ Forig = paPass->getOrigFunctionFromClone(F);
+ }
+ //we got the original function
+
+ for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {
+ if (LoadInst *LI = dyn_cast<LoadInst>(&*I)) {
+ //we need to get the LI from the original function
+ Value *P = LI->getPointerOperand();
+ if (isClonedFunc) {
+ assert(FI->NewToOldValueMap.count(LI) && " not in the value map \n");
+ const LoadInst *temp = dyn_cast<LoadInst>(FI->NewToOldValueMap[LI]);
+ assert(temp && " Instruction not there in the NewToOldValue map");
+ const Value *Ptr = temp->getPointerOperand();
+ addLSChecks(P, Ptr, LI, Forig);
+ } else {
+ addLSChecks(P, P, LI, Forig);
+ }
+ } else if (StoreInst *SI = dyn_cast<StoreInst>(&*I)) {
+ Value *P = SI->getPointerOperand();
+ if (isClonedFunc) {
+ assert(FI->NewToOldValueMap.count(SI) && " not in the value map \n");
+ const StoreInst *temp = dyn_cast<StoreInst>(FI->NewToOldValueMap[SI]);
+ assert(temp && " Instruction not there in the NewToOldValue map");
+ const Value *Ptr = temp->getPointerOperand();
+ addLSChecks(P, Ptr, SI, Forig);
+ } else {
+ addLSChecks(P, P, SI, Forig);
+ }
+ } else if (CallInst *CI = dyn_cast<CallInst>(&*I)) {
+ Value *FunctionOp = CI->getOperand(0);
+ if (!isa<Function>(FunctionOp)) {
+ if (isClonedFunc) {
+ assert(FI->NewToOldValueMap.count(CI) && " not in the value map \n");
+ const CallInst *temp = dyn_cast<CallInst>(FI->NewToOldValueMap[CI]);
+ assert(temp && " Instruction not there in the NewToOldValue map");
+ const Value* FunctionOp1 = temp->getOperand(0);
+ addLSChecks(FunctionOp, FunctionOp1, CI, Forig);
+ } else {
+ addLSChecks(FunctionOp, FunctionOp, CI, Forig);
+ }
+ }
+ }
+ }
}
}
#endif
-//
-// Method: getDSGraph()
-//
-// Description:
-// Return the DSGraph for the given function. This method automatically
-// selects the correct pass to query for the graph based upon whether we're
-// doing user-space or kernel analysis.
-//
-DSGraph &
-InsertPoolChecks::getDSGraph(Function & F) {
-#ifndef LLVA_KERNEL
- return equivPass->getDSGraph(F);
-#else
- return TDPass->getDSGraph(F);
-#endif
+void InsertPoolChecks::addGetElementPtrChecks(Module &M) {
+ std::vector<Instruction *> & UnsafeGetElemPtrs = cuaPass->getUnsafeGetElementPtrsFromABC();
+ std::vector<Instruction *>::const_iterator iCurrent = UnsafeGetElemPtrs.begin(), iEnd = UnsafeGetElemPtrs.end();
+ for (; iCurrent != iEnd; ++iCurrent) {
+ // We have the GetElementPtr
+ if (!isa<GetElementPtrInst>(*iCurrent)) {
+ //Then this must be a function call
+ //FIXME, get strcpy and others from the backup dir and adjust them for LLVA
+ //Right now I just add memset &llva_memcpy for LLVA
+ // std::cerr << " function call \n";
+#ifdef LLVA_KERNEL
+ CallInst *CI = dyn_cast<CallInst>(*iCurrent);
+ if (CI && (!DisableIntrinsicChecks)) {
+ Value *Fop = CI->getOperand(0);
+ Function *F = CI->getParent()->getParent();
+ if (Fop->getName() == "llva_memcpy") {
+ Value *PH = getPoolHandle(CI->getOperand(1), F);
+ Instruction *InsertPt = CI;
+ if (!PH) {
+ ++NullChecks;
+ ++MissedNullChecks;
+
+ // Don't bother to insert the NULL check unless the user asked
+ if (!EnableNullChecks)
+ continue;
+ PH = Constant::getNullValue(PointerType::get(Type::SByteTy));
+ }
+ CastInst *CastCIUint =
+ new CastInst(CI->getOperand(1), Type::UIntTy, "node.lscasted", InsertPt);
+ CastInst *CastCIOp3 =
+ new CastInst(CI->getOperand(3), Type::UIntTy, "node.lscasted", InsertPt);
+ Instruction *Bop = BinaryOperator::create(Instruction::Add, CastCIUint,
+ CastCIOp3, "memcpyadd",InsertPt);
+
+ // Create instructions to cast the checked pointer and the checked pool
+ // into sbyte pointers.
+ CastInst *CastSourcePointer =
+ new CastInst(CI->getOperand(1),
+ PointerType::get(Type::SByteTy), "memcpy.1.casted", InsertPt);
+ CastInst *CastCI =
+ new CastInst(Bop,
+ PointerType::get(Type::SByteTy), "mempcy.2.casted", InsertPt);
+ CastInst *CastPHI =
+ new CastInst(PH,
+ PointerType::get(Type::SByteTy), "poolhandle.lscasted", InsertPt);
+
+ // Create the call to poolcheck
+ std::vector<Value *> args(1,CastPHI);
+ args.push_back(CastSourcePointer);
+ args.push_back(CastCI);
+ new CallInst(PoolCheckArray,args,"", InsertPt);
+#if 0
+ } else if (Fop->getName() == "memset") {
+ Value *PH = getPoolHandle(CI->getOperand(1), F);
+ Instruction *InsertPt = CI->getNext();
+ if (!PH) {
+ NullChecks++;
+ // Don't bother to insert the NULL check unless the user asked
+ if (!EnableNullChecks)
+ continue;
+ PH = Constant::getNullValue(PointerType::get(Type::SByteTy));
+ }
+ CastInst *CastCIUint =
+ new CastInst(CI, Type::UIntTy, "node.lscasted", InsertPt);
+ CastInst *CastCIOp3 =
+ new CastInst(CI->getOperand(3), Type::UIntTy, "node.lscasted", InsertPt);
+ Instruction *Bop = BinaryOperator::create(Instruction::Add, CastCIUint,
+ CastCIOp3, "memsetadd",InsertPt);
+
+ // Create instructions to cast the checked pointer and the checked pool
+ // into sbyte pointers.
+ CastInst *CastSourcePointer =
+ new CastInst(CI->getOperand(1),
+ PointerType::get(Type::SByteTy), "memset.1.casted", InsertPt);
+ CastInst *CastCI =
+ new CastInst(Bop,
+ PointerType::get(Type::SByteTy), "memset.2.casted", InsertPt);
+ CastInst *CastPHI =
+ new CastInst(PH,
+ PointerType::get(Type::SByteTy), "poolhandle.lscasted", InsertPt);
+
+ // Create the call to poolcheck
+ std::vector<Value *> args(1,CastPHI);
+ args.push_back(CastSourcePointer);
+ args.push_back(CastCI);
+ new CallInst(PoolCheckArray,args,"", InsertPt);
+#endif
+ }
+ }
+#endif
+ continue;
+ }
+ GetElementPtrInst *GEP = cast<GetElementPtrInst>(*iCurrent);
+ Function *F = GEP->getParent()->getParent();
+ // Now we need to decide if we need to pass in the alignmnet
+ //for the poolcheck
+ // if (getDSNodeOffset(GEP->getPointerOperand(), F)) {
+ // std::cerr << " we don't handle middle of structs yet\n";
+ //assert(!getDSNodeOffset(GEP->getPointerOperand(), F) && " we don't handle middle of structs yet\n");
+ // ++MissChecks;
+ // continue;
+ // }
+
+#ifndef LLVA_KERNEL
+ PA::FuncInfo *FI = paPass->getFuncInfoOrClone(*F);
+ Instruction *Casted = GEP;
+ if (!FI->ValueMap.empty()) {
+ assert(FI->ValueMap.count(GEP) && "Instruction not in the value map \n");
+ Instruction *temp = dyn_cast<Instruction>(FI->ValueMap[GEP]);
+ assert(temp && " Instruction not there in the Value map");
+ Casted = temp;
+ }
+ if (GetElementPtrInst *GEPNew = dyn_cast<GetElementPtrInst>(Casted)) {
+ Value *PH = getPoolHandle(GEP, F, *FI);
+ if (PH && isa<ConstantPointerNull>(PH)) continue;
+ if (!PH) {
+ Value *PointerOperand = GEPNew->getPointerOperand();
+ if (ConstantExpr *cExpr = dyn_cast<ConstantExpr>(PointerOperand)) {
+ if (cExpr->getOpcode() == Instruction::Cast)
+ PointerOperand = cExpr->getOperand(0);
+ }
+ if (GlobalVariable *GV = dyn_cast<GlobalVariable>(PointerOperand)) {
+ if (const ArrayType *AT = dyn_cast<ArrayType>(GV->getType()->getElementType())) {
+ // We need to insert an actual check. It could be a select
+ // instruction.
+ // First get the size.
+ // This only works for one or two dimensional arrays.
+ if (GEPNew->getNumOperands() == 2) {
+ Value *secOp = GEPNew->getOperand(1);
+ if (secOp->getType() != Type::UIntTy) {
+ secOp = new CastInst(secOp, Type::UIntTy,
+ secOp->getName()+".ec.casted", Casted);
+ }
+
+ const Type* csiType = Type::getPrimitiveType(Type::IntTyID);
+ std::vector<Value *> args(1,secOp);
+ args.push_back(ConstantInt::get(csiType,AT->getNumElements()));
+ new CallInst(ExactCheck,args,"", Casted);
+ DEBUG(std::cerr << "Inserted exact check call Instruction \n");
+ continue;
+ } else if (GEPNew->getNumOperands() == 3) {
+ if (ConstantInt *COP = dyn_cast<ConstantInt>(GEPNew->getOperand(1))) {
+ // FIXME: assuming that the first array index is 0
+ assert((COP->getZExtValue() == 0) && "non zero array index\n");
+ Value * secOp = GEPNew->getOperand(2);
+ if (secOp->getType() != Type::UIntTy) {
+ secOp = new CastInst(secOp, Type::UIntTy,
+ secOp->getName()+".ec2.casted", Casted);
+ }
+ std::vector<Value *> args(1,secOp);
+ const Type* csiType = Type::getPrimitiveType(Type::IntTyID);
+ args.push_back(ConstantInt::get(csiType,AT->getNumElements()));
+ new CallInst(ExactCheck, args, "", Casted->getNext());
+ continue;
+ } else {
+ // Handle non constant index two dimensional arrays later
+ abort();
+ }
+ } else {
+ // Handle Multi dimensional cases later
+ DEBUG(std::cerr << "WARNING: Handle multi dimensional globals later\n");
+ (*iCurrent)->dump();
+ }
+ }
+ DEBUG(std::cerr << " Global variable ok \n");
+ }
+
+ // These must be real unknowns and they will be handled anyway
+ // std::cerr << " WARNING, DID NOT HANDLE \n";
+ // (*iCurrent)->dump();
+ continue ;
+ } else {
+ if (Casted->getType() != PointerType::get(Type::SByteTy)) {
+ Casted = new CastInst(Casted,PointerType::get(Type::SByteTy),
+ (Casted)->getName()+".pc.casted",
+ (Casted)->getNext());
+ }
+ std::vector<Value *> args(1, PH);
+ args.push_back(Casted);
+ // Insert it
+ new CallInst(PoolCheck,args, "",Casted->getNext());
+ DEBUG(std::cerr << "inserted instrcution \n");
+ }
+ }
+#else
+ //
+ // Get the pool handle associated with the pointer operand.
+ //
+ Value *PH = getPoolHandle(GEP->getPointerOperand(), F);
+ GetElementPtrInst *GEPNew = GEP;
+ Instruction *Casted = GEP;
+
+ DSGraph & TDG = TDPass->getDSGraph(*F);
+ DSNode * Node = TDG.getNodeForValue(GEP).getNode();
+
+ DEBUG(std::cerr << "LLVA: addGEPChecks: Pool " << PH << " Node ");
+ DEBUG(std::cerr << Node << std::endl);
+
+ Value *PointerOperand = GEPNew->getPointerOperand();
+ if (ConstantExpr *cExpr = dyn_cast<ConstantExpr>(PointerOperand)) {
+ if (cExpr->getOpcode() == Instruction::Cast)
+ PointerOperand = cExpr->getOperand(0);
+ }
+ if (GlobalVariable *GV = dyn_cast<GlobalVariable>(PointerOperand)) {
+ if (const ArrayType *AT = dyn_cast<ArrayType>(GV->getType()->getElementType())) {
+ // we need to insert an actual check
+ // It could be a select instruction
+ // First get the size
+ // This only works for one or two dimensional arrays
+ if (GEPNew->getNumOperands() == 2) {
+ Value *secOp = GEPNew->getOperand(1);
+ if (secOp->getType() != Type::UIntTy) {
+ secOp = new CastInst(secOp, Type::UIntTy,
+ secOp->getName()+".ec3.casted", Casted);
+ }
+
+ std::vector<Value *> args(1,secOp);
+ const Type* csiType = Type::getPrimitiveType(Type::IntTyID);
+ args.push_back(ConstantInt::get(csiType,AT->getNumElements()));
+ CallInst *newCI = new CallInst(ExactCheck,args,"", Casted);
+ ++BoundChecks;
+ // DEBUG(std::cerr << "Inserted exact check call Instruction \n");
+ continue;
+ } else if (GEPNew->getNumOperands() == 3) {
+ if (ConstantInt *COP = dyn_cast<ConstantInt>(GEPNew->getOperand(1))) {
+ //FIXME assuming that the first array index is 0
+ assert((COP->getZExtValue() == 0) && "non zero array index\n");
+ Value * secOp = GEPNew->getOperand(2);
+ if (secOp->getType() != Type::UIntTy) {
+ secOp = new CastInst(secOp, Type::UIntTy,
+ secOp->getName()+".ec4.casted", Casted);
+ }
+ std::vector<Value *> args(1,secOp);
+ const Type* csiType = Type::getPrimitiveType(Type::IntTyID);
+ args.push_back(ConstantInt::get(csiType,AT->getNumElements()));
+ CallInst *newCI = new CallInst(ExactCheck,args,"", Casted->getNext());
+ ++BoundChecks;
+ continue;
+ } else {
+ //Handle non constant index two dimensional arrays later
+ abort();
+ }
+ } else {
+ //Handle Multi dimensional cases later
+ std::cerr << "WARNING: Handle multi dimensional globals later\n";
+ (*iCurrent)->dump();
+ ++MissedMultDimArrayChecks;
+ }
+ DEBUG(std::cerr << " Global variable ok \n");
+ }
+ }
+
+#if 0
+ //No checks for incomplete nodes
+ if (!EnableIncompleteChecks) {
+ if (Node->isIncomplete()) {
+ ++MissedNullChecks;
+ continue;
+ }
+ }
+#endif
+
+ //
+ // We cannot insert an exactcheck(). Insert a pool check.
+ //
+ // FIXME:
+ // Currently, we cannot register stack or global memory with pools. If
+ // the node is from alloc() or is a global, do not insert a poolcheck.
+ //
+#if 0
+ if ((!PH) || (Node->isAllocaNode()) || (Node->isGlobalNode())) {
+#else
+ if (!PH) {
+#endif
+ ++NullChecks;
+ if (!PH) ++MissedNullChecks;
+#if 0
+ if (Node->isAllocaNode()) ++MissedStackChecks;
+ if (Node->isGlobalNode()) ++MissedGlobalChecks;
+#endif
+ // Don't bother to insert the NULL check unless the user asked
+ if (!EnableNullChecks)
+ continue;
+ PH = Constant::getNullValue(PointerType::get(Type::SByteTy));
+ DEBUG(std::cerr << "missing a GEP check for" << GEP << "alloca case?\n");
+ } else {
+ //
+ // Determine whether the pool handle dominates the pool check.
+ // If not, then don't insert it.
+ //
+
+ //
+ // FIXME:
+ // This domination check is too restrictive; it eliminates pools that do
+ // dominate but are outside of the current basic block.
+ //
+ // Only add the pool check if the pool is a global value or it belongs
+ // to the same basic block.
+ //
+ if (isa<GlobalValue>(PH)) {
+ ++FullChecks;
+ } else if (isa<Instruction>(PH)) {
+ Instruction * IPH = (Instruction *)(PH);
+ if (IPH->getParent() == Casted->getParent()) {
+ //
+ // If the instructions belong to the same basic block, ensure that
+ // the pool dominates the load/store.
+ //
+ Instruction * IP = IPH;
+ for (IP=IPH; (IP->isTerminator()) || (IP==Casted); IP=IP->getNext()) {
+ ;
+ }
+ if (IP == Casted)
+ ++FullChecks;
+ else {
+ ++MissChecks;
+ continue;
+ }
+ } else {
+ ++MissChecks;
+ continue;
+ }
+ } else {
+ ++MissChecks;
+ continue;
+ }
+ }
+
+ //
+ // If this is a complete node, insert a poolcheck.
+ // If this is an icomplete node, insert a poolcheckarray.
+ //
+ Instruction *InsertPt = Casted->getNext();
+ if (Casted->getType() != PointerType::get(Type::SByteTy)) {
+ Casted = new CastInst(Casted,PointerType::get(Type::SByteTy),
+ (Casted)->getName()+".pc2.casted",InsertPt);
+ }
+ Instruction *CastedPointerOperand = new CastInst(PointerOperand,
+ PointerType::get(Type::SByteTy),
+ PointerOperand->getName()+".casted",InsertPt);
+ Instruction *CastedPH = new CastInst(PH,
+ PointerType::get(Type::SByteTy),
+ "ph",InsertPt);
+ if (Node->isIncomplete()) {
+ std::vector<Value *> args(1, CastedPH);
+ args.push_back(CastedPointerOperand);
+ args.push_back(Casted);
+ CallInst * newCI = new CallInst(PoolCheckArray,args, "",InsertPt);
+ } else {
+ std::vector<Value *> args(1, CastedPH);
+ args.push_back(Casted);
+ CallInst * newCI = new CallInst(PoolCheck,args, "",InsertPt);
+ }
+#endif
+ }
+}
+
+void InsertPoolChecks::addPoolCheckProto(Module &M) {
+ const Type * VoidPtrType = PointerType::get(Type::SByteTy);
+ /*
+ const Type *PoolDescType = ArrayType::get(VoidPtrType, 50);
+ // StructType::get(make_vector<const Type*>(VoidPtrType, VoidPtrType,
+ // Type::UIntTy, Type::UIntTy, 0));
+ const Type * PoolDescTypePtr = PointerType::get(PoolDescType);
+ */
+
+ std::vector<const Type *> Arg(1, VoidPtrType);
+ Arg.push_back(VoidPtrType);
+ FunctionType *PoolCheckTy =
+ FunctionType::get(Type::VoidTy,Arg, false);
+ PoolCheck = M.getOrInsertFunction("poolcheck", PoolCheckTy);
+
+ std::vector<const Type *> Arg2(1, VoidPtrType);
+ Arg2.push_back(VoidPtrType);
+ Arg2.push_back(VoidPtrType);
+ FunctionType *PoolCheckArrayTy =
+ FunctionType::get(Type::VoidTy,Arg2, false);
+ PoolCheckArray = M.getOrInsertFunction("poolcheckarray", PoolCheckArrayTy);
+
+ std::vector<const Type *> FArg2(1, Type::UIntTy);
+ FArg2.push_back(Type::IntTy);
+ FunctionType *ExactCheckTy = FunctionType::get(Type::VoidTy, FArg2, false);
+ ExactCheck = M.getOrInsertFunction("exactcheck", ExactCheckTy);
+
+ std::vector<const Type *> FArg3(1, Type::UIntTy);
+ FArg3.push_back(VoidPtrType);
+ FArg3.push_back(VoidPtrType);
+ FunctionType *FunctionCheckTy = FunctionType::get(Type::VoidTy, FArg3, true);
+ FunctionCheck = M.getOrInsertFunction("funccheck", FunctionCheckTy);
+
}
DSNode* InsertPoolChecks::getDSNode(const Value *V, Function *F) {
- DSGraph &TDG = getDSGraph(*F);
+#ifndef LLVA_KERNEL
+ DSGraph &TDG = equivPass->getDSGraph(*F);
+#else
+ DSGraph &TDG = TDPass->getDSGraph(*F);
+#endif
DSNode *DSN = TDG.getNodeForValue((Value *)V).getNode();
return DSN;
}
unsigned InsertPoolChecks::getDSNodeOffset(const Value *V, Function *F) {
- DSGraph &TDG = getDSGraph(*F);
+#ifndef LLVA_KERNEL
+ DSGraph &TDG = equivPass->getDSGraph(*F);
+#else
+ DSGraph &TDG = TDPass->getDSGraph(*F);
+#endif
return TDG.getNodeForValue((Value *)V).getOffset();
}
-
#ifndef LLVA_KERNEL
Value *InsertPoolChecks::getPoolHandle(const Value *V, Function *F, PA::FuncInfo &FI, bool collapsed) {
const DSNode *Node = getDSNode(V,F);
@@ -3659,58 +838,14 @@
if (!collapsed && CollapsedPoolPtrs.count(F)) {
Value *v = I->second;
- if (CollapsedPoolPtrs[F].find(I->second) != CollapsedPoolPtrs[F].end()) {
+ if (CollapsedPoolPtrs[F].find(I->second) !=
+ CollapsedPoolPtrs[F].end()) {
#ifdef DEBUG
- std::cerr << "Collapsed pools \n";
+ std::cerr << "Collapsed pools \n";
#endif
- return Constant::getNullValue(PoolDescPtrTy);
+ return Constant::getNullValue(PoolDescPtrTy);
} else {
- return v;
- }
- } else {
- return I->second;
- }
- }
- return 0;
-}
-
-Value *
-InsertPoolChecks::getPoolHandle(const Value *V, Function *F, bool collapsed) {
- const DSNode *Node = getDSNode(V,F);
- PA::FuncInfo * FI = paPass->getFuncInfoOrClone(*F);
-
- // Get the pool handle for this DSNode...
- // assert(!Node->isUnknownNode() && "Unknown node \n");
- Type *VoidPtrType = PointerType::get(Type::SByteTy);
- Type *PoolDescType = ArrayType::get(VoidPtrType, 50);
- Type *PoolDescPtrTy = PointerType::get(PoolDescType);
- if (!Node) {
- return 0; //0 means there is no isse with the value, otherwise there will be a callnode
- }
- if (Node->isUnknownNode()) {
- //FIXME this should be in a top down pass or propagated like collapsed pools below
- if (!collapsed) {
- assert(!getDSNodeOffset(V, F) && " we don't handle middle of structs yet\n");
- return Constant::getNullValue(PoolDescPtrTy);
- }
- }
- std::map<const DSNode*, Value*>::iterator I = FI->PoolDescriptors.find(Node);
- map <Function *, set<Value *> > &
- CollapsedPoolPtrs = efPass->CollapsedPoolPtrs;
-
- if (I != FI->PoolDescriptors.end()) {
- // Check that the node pointed to by V in the TD DS graph is not
- // collapsed
-
- if (!collapsed && CollapsedPoolPtrs.count(F)) {
- Value *v = I->second;
- if (CollapsedPoolPtrs[F].find(I->second) != CollapsedPoolPtrs[F].end()) {
-#ifdef DEBUG
- std::cerr << "Collapsed pools \n";
-#endif
- return Constant::getNullValue(PoolDescPtrTy);
- } else {
- return v;
+ return v;
}
} else {
return I->second;
@@ -3719,20 +854,16 @@
return 0;
}
#else
-Value *
-InsertPoolChecks::getPoolHandle(const Value *V, Function *F) {
- DSGraph &TDG = getDSGraph(*F);
- DSNode *Node = TDG.getNodeForValue((Value *)V).getNode();
-
- // Register that we will need allocations with this DSNode registered.
- if (Node)
- PHNeeded.insert (Node);
-
+Value *InsertPoolChecks::getPoolHandle(const Value *V, Function *F) {
+ DSGraph &TDG = TDPass->getDSGraph(*F);
+ const DSNode *Node = TDG.getNodeForValue((Value *)V).getNode();
// Get the pool handle for this DSNode...
// assert(!Node->isUnknownNode() && "Unknown node \n");
// if (Node->isUnknownNode()) {
// return 0;
// }
- return getPD (Node, *F->getParent());
+ if ((TDG.getPoolDescriptorsMap()).count(Node))
+ return (TDG.getPoolDescriptorsMap()[Node]->getMetaPoolValue());
+ return 0;
}
#endif
diff --git a/safecode/lib/Makefile b/safecode/lib/Makefile
index 99c31f2..159129f 100755
--- a/safecode/lib/Makefile
+++ b/safecode/lib/Makefile
@@ -1,6 +1,6 @@
LEVEL = ..
-PARALLEL_DIRS = ArrayBoundChecks ConvertUnsafeAllocas InsertPoolChecks StackSafety PointerChecks ProofWrap
+PARALLEL_DIRS = ArrayBoundChecks ConvertUnsafeAllocas InsertPoolChecks StackSafety PointerChecks
include $(LEVEL)/Makefile.common
diff --git a/safecode/runtime/KPoolCheck/ExactCheck.c b/safecode/runtime/KPoolCheck/ExactCheck.c
deleted file mode 100755
index ae775b9..0000000
--- a/safecode/runtime/KPoolCheck/ExactCheck.c
+++ /dev/null
@@ -1,104 +0,0 @@
-/*===- ExactCheck.cpp - Implementation of exactcheck functions ------------===*/
-/* */
-/* The LLVM Compiler Infrastructure */
-/* */
-/* This file was developed by the LLVM research group and is distributed */
-/* under the University of Illinois Open Source License. See LICENSE.TXT for */
-/* details. */
-/* */
-/*===----------------------------------------------------------------------===*/
-/* */
-/* This file implements the exactcheck family of functions. */
-/* */
-/*===----------------------------------------------------------------------===*/
-
-#include "PoolCheck.h"
-#include "PoolSystem.h"
-#include "adl_splay.h"
-#ifdef LLVA_KERNEL
-#include <stdarg.h>
-#endif
-#define DEBUG(x)
-
-/* Flag whether to print error messages on bounds violations */
-int ec_do_fail = 1;
-
-extern int stat_exactcheck;
-extern int stat_exactcheck2;
-extern int stat_exactcheck3;
-
-void * exactcheck(int a, int b, void * result) {
- ++stat_exactcheck;
- if ((0 > a) || (a >= b)) {
- if(ec_do_fail) poolcheckfail ("exact check failed", (a), (void*)__builtin_return_address(0));
- if(ec_do_fail) poolcheckfail ("exact check failed", (b), (void*)__builtin_return_address(0));
- }
- return result;
-}
-
-void * exactcheck2(signed char *base, signed char *result, unsigned size) {
- ++stat_exactcheck2;
- if ((result < base) || (result >= base + size )) {
- if(ec_do_fail) poolcheckfail("Array bounds violation detected ", (unsigned)base, (void*)__builtin_return_address(0));
- }
- return result;
-}
-
-void * exactcheck2a(signed char *base, signed char *result, unsigned size) {
- ++stat_exactcheck2;
- if (result >= base + size ) {
- if(ec_do_fail) poolcheckfail("Array bounds violation detected ", (unsigned)base, (void*)__builtin_return_address(0));
- }
- return result;
-}
-
-void * exactcheck3(signed char *base, signed char *result, signed char * end) {
- ++stat_exactcheck3;
- if ((result < base) || (result > end )) {
- if(ec_do_fail) poolcheckfail("Array bounds violation detected ", (unsigned)base, (void*)__builtin_return_address(0));
- }
- return result;
-}
-
-void funccheck (unsigned num, void *f, void *t1, void *t2, void *t3,
- void *t4, void *t5, void *t6) {
- if ((t1) && (f == t1)) return;
- if ((t2) && (f == t2)) return;
- if ((t3) && (f == t3)) return;
- if ((t4) && (f == t4)) return;
- if ((t5) && (f == t5)) return;
- if ((t6) && (f == t6)) return;
- if (ec_do_fail) poolcheckfail ("funccheck failed", f, (void*)__builtin_return_address(0));
- return;
-}
-
-void funccheck_t (unsigned num, void * f, void ** table) {
- unsigned int index;
- /*
- * Look for the pointer in the big table
- */
- for (index = 0; index < num; ++index) {
- if (f == table[index]) {
- return;
- }
- }
-
- if (ec_do_fail) poolcheckfail ("funccheck_t failed", f, (void*)__builtin_return_address(0));
-}
-
-struct node {
- void* left;
- void* right;
- char* key;
- char* end;
- void* tag;
-};
-
-void * getBegin (void * node) {
- return ((struct node *)(node))->key;
-}
-
-void * getEnd (void * node) {
- return ((struct node *)(node))->end;
-}
-
diff --git a/safecode/runtime/KPoolCheck/Makefile b/safecode/runtime/KPoolCheck/Makefile
deleted file mode 100755
index af7b14a..0000000
--- a/safecode/runtime/KPoolCheck/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-LEVEL = ../..
-BYTECODE_LIBRARY=1
-LIBRARYNAME=kpoolcheck_rt
-
-include $(LEVEL)/Makefile.common
-
-# Always build optimized and debug versions
-all:: $(LIBNAME_OBJO) $(LIBNAME_OBJG)
diff --git a/safecode/runtime/KPoolCheck/PoolCheck.c b/safecode/runtime/KPoolCheck/PoolCheck.c
deleted file mode 100755
index c5f21b3..0000000
--- a/safecode/runtime/KPoolCheck/PoolCheck.c
+++ /dev/null
@@ -1,849 +0,0 @@
-/*===- PoolCheck.cpp - Implementation of poolcheck runtime ----------------===*/
-/* */
-/* The LLVM Compiler Infrastructure */
-/* */
-/* This file was developed by the LLVM research group and is distributed */
-/* under the University of Illinois Open Source License. See LICENSE.TXT for */
-/* details. */
-/* */
-/*===----------------------------------------------------------------------===*/
-/* */
-/* This file implements the poolcheck interface w/ metapools and opaque */
-/* pool ids. */
-/* */
-/*===----------------------------------------------------------------------===*/
-
-#include "PoolCheck.h"
-#include "PoolSystem.h"
-#include "adl_splay.h"
-#ifdef LLVA_KERNEL
-#include <stdarg.h>
-#endif
-#define DEBUG(x)
-
-/* Flag whether we are pchk_ready to perform pool operations */
-int pchk_ready = 0;
-
-/* Flag whether to do profiling */
-/* profiling only works if this library is compiled to a .o file, not llvm */
-static const int do_profile = 0;
-
-/* Flag whether to support out of bounds pointer rewriting */
-static const int use_oob = 0;
-
-/* Flag whether to print error messages on bounds violations */
-static const int do_fail = 0;
-
-/* Statistic counters */
-int stat_poolcheck=0;
-int stat_poolcheckarray=0;
-int stat_poolcheckarray_i=0;
-int stat_boundscheck=0;
-int stat_boundscheck_i=0;
-
-/* Global splay for holding the interrupt context */
-void * ICSplay;
-
-/* Global splay for holding the integer states */
-MetaPoolTy IntegerStatePool;
-
-extern void llva_load_lif (unsigned int enable);
-extern unsigned int llva_save_lif (void);
-
-
-static unsigned
-disable_irqs ()
-{
- unsigned int is_set;
- is_set = llva_save_lif ();
- llva_load_lif (0);
- return is_set;
-}
-
-static void
-enable_irqs (int is_set)
-{
- llva_load_lif (is_set);
-}
-
-#define PCLOCK() int pc_i = disable_irqs();
-#define PCLOCK2() pc_i = disable_irqs();
-#define PCUNLOCK() enable_irqs(pc_i);
-
-#define maskaddr(_a) ((void*) ((unsigned)_a & ~(4096 - 1)))
-
-static int isInCache(MetaPoolTy* MP, void* addr) {
- addr = maskaddr(addr);
- if (!addr) return 0;
- if (MP->cache0 == addr)
- return 1;
- if (MP->cache1 == addr)
- return 2;
- if (MP->cache2 == addr)
- return 3;
- if (MP->cache3 == addr)
- return 4;
- return 0;
-}
-
-static void mtfCache(MetaPoolTy* MP, int ent) {
- void* z = MP->cache0;
- switch (ent) {
- case 2:
- MP->cache0 = MP->cache1;
- MP->cache1 = z;
- break;
- case 3:
- MP->cache0 = MP->cache1;
- MP->cache1 = MP->cache2;
- MP->cache2 = z;
- break;
- case 4:
- MP->cache0 = MP->cache1;
- MP->cache1 = MP->cache2;
- MP->cache2 = MP->cache3;
- MP->cache3 = z;
- break;
- default:
- break;
- }
- return;
-}
-
-static int insertCache(MetaPoolTy* MP, void* addr) {
- addr = maskaddr(addr);
- if (!addr) return 0;
- if (!MP->cache0) {
- MP->cache0 = addr;
- return 1;
- }
- else if (!MP->cache1) {
- MP->cache1 = addr;
- return 2;
- }
- else if (!MP->cache2) {
- MP->cache2 = addr;
- return 3;
- }
- else {
- MP->cache3 = addr;
- return 4;
- }
-}
-
-/*
- * Function: pchk_init()
- *
- * Description:
- * Initialization function to be called when the memory allocator run-time
- * intializes itself.
- *
- * Preconditions:
- * 1) The OS kernel is able to handle callbacks from the Execution Engine.
- */
-void pchk_init(void) {
-
- /* initialize runtime */
- adl_splay_libinit(poolcheckmalloc);
-
- /*
- * Register all of the global variables in their respective meta pools.
- */
- poolcheckglobals();
-
- /*
- * Flag that we're pchk_ready to rumble!
- */
- pchk_ready = 1;
- return;
-}
-
-/* Register a slab */
-void pchk_reg_slab(MetaPoolTy* MP, void* PoolID, void* addr, unsigned len) {
-#if 0
- if (!MP) { poolcheckinfo("reg slab on null pool", (int)addr); return; }
-#else
- if (!MP) { return; }
-#endif
- PCLOCK();
- adl_splay_insert(&MP->Slabs, addr, len, PoolID);
- PCUNLOCK();
-}
-
-/* Remove a slab */
-void pchk_drop_slab(MetaPoolTy* MP, void* PoolID, void* addr) {
- if (!MP) return;
- /* TODO: check that slab's tag is == PoolID */
- PCLOCK();
- adl_splay_delete(&MP->Slabs, addr);
- PCUNLOCK();
-}
-
-/* Register a non-pool allocated object */
-void pchk_reg_obj(MetaPoolTy* MP, void* addr, unsigned len) {
- unsigned int index;
-#if 0
- if (!MP) { poolcheckinfo("reg obj on null pool", addr); return; }
-#else
- if (!MP) { return; }
-#endif
-#if 0
- if (pchk_ready) poolcheckinfo2 ("pchk_reg_obj", addr, len);
-#endif
- PCLOCK();
-#if 0
- {
- void * S = addr;
- unsigned len, tag = 0;
- if ((pchk_ready) && (adl_splay_retrieve(&MP->Objs, &S, &len, &tag)))
- poolcheckinfo2 ("regobj: Object exists", __builtin_return_address(0), tag);
- }
-#endif
-
- adl_splay_insert(&MP->Objs, addr, len, __builtin_return_address(0));
-#if 1
- /*
- * Look for an entry in the cache that matches. If it does, just erase it.
- */
- for (index=0; index < 4; ++index) {
- if ((MP->start[index] <= addr) &&
- (MP->start[index]+MP->length[index] >= addr)) {
- MP->start[index] = 0;
- MP->length[index] = 0;
- MP->cache[index] = 0;
- }
- }
-#endif
- PCUNLOCK();
-}
-
-void pchk_reg_stack (MetaPoolTy* MP, void* addr, unsigned len) {
- unsigned int index;
- if (!MP) { return; }
- PCLOCK();
-
- adl_splay_insert(&MP->Objs, addr, len, __builtin_return_address(0));
-#if 1
- /*
- * Look for an entry in the cache that matches. If it does, just erase it.
- */
- for (index=0; index < 4; ++index) {
- if ((MP->start[index] <= addr) &&
- (MP->start[index]+MP->length[index] >= addr)) {
- MP->start[index] = 0;
- MP->length[index] = 0;
- MP->cache[index] = 0;
- }
- }
-#endif
- PCUNLOCK();
-}
-
-void pchk_reg_ic (int sysnum, int a, int b, int c, int d, int e, int f, void* addr) {
- PCLOCK();
- adl_splay_insert(&ICSplay, addr, (28*4), 0);
- PCUNLOCK();
-}
-
-void pchk_reg_ic_memtrap (void * p, void* addr) {
- PCLOCK();
- adl_splay_insert(&ICSplay, addr, (28*4), 0);
- PCUNLOCK();
-}
-
-void pchk_reg_int (void* addr) {
- unsigned int index;
- if (!pchk_ready) return;
- PCLOCK();
- adl_splay_insert(&(IntegerStatePool.Objs), addr, 72, __builtin_return_address(0));
-#if 1
- /*
- * Look for an entry in the cache that matches. If it does, just erase it.
- */
- for (index=0; index < 4; ++index) {
- if ((IntegerStatePool.start[index] <= addr) &&
- (IntegerStatePool.start[index]+IntegerStatePool.length[index] >= addr)) {
- IntegerStatePool.start[index] = 0;
- IntegerStatePool.length[index] = 0;
- IntegerStatePool.cache[index] = 0;
- }
- }
-#endif
- PCUNLOCK();
-}
-
-/* Remove a non-pool allocated object */
-void pchk_drop_obj(MetaPoolTy* MP, void* addr) {
- unsigned int index;
- if (!MP) return;
- PCLOCK();
- adl_splay_delete(&MP->Objs, addr);
-#if 0
- {
- void * S = addr;
- unsigned len, tag;
- if (adl_splay_retrieve(&MP->Objs, &S, &len, &tag))
- poolcheckinfo ("drop_obj: Failed to remove: 1", addr, tag);
- }
-#endif
- /*
- * See if the object is within the cache. If so, remove it from the cache.
- */
- for (index=0; index < 4; ++index) {
- if ((MP->start[index] <= addr) &&
- (MP->start[index]+MP->length[index] >= addr)) {
- MP->start[index] = 0;
- MP->length[index] = 0;
- MP->cache[index] = 0;
- }
- }
- PCUNLOCK();
-}
-
-void pchk_drop_stack (MetaPoolTy* MP, void* addr) {
- unsigned int index;
- if (!MP) return;
- PCLOCK();
- adl_splay_delete(&MP->Objs, addr);
-
- /*
- * See if the object is within the cache. If so, remove it from the cache.
- */
- for (index=0; index < 4; ++index) {
- if ((MP->start[index] <= addr) &&
- (MP->start[index]+MP->length[index] >= addr)) {
- MP->start[index] = 0;
- MP->length[index] = 0;
- MP->cache[index] = 0;
- }
- }
- PCUNLOCK();
-}
-
-void pchk_drop_ic (void* addr) {
- PCLOCK();
- adl_splay_delete(&ICSplay, addr);
- PCUNLOCK();
-}
-
-/*
- * Function: pchk_drop_ic_interrupt()
- *
- * Description:
- * Identical to pchk_drop_ic but takes an additional argument to make the
- * assembly dispatching code easier and faster.
- */
-void pchk_drop_ic_interrupt (int intnum, void* addr) {
- PCLOCK();
- adl_splay_delete(&ICSplay, addr);
- PCUNLOCK();
-}
-
-/*
- * Function: pchk_drop_ic_memtrap()
- *
- * Description:
- * Identical to pchk_drop_ic but takes an additional argument to make the
- * assembly dispatching code easier and faster.
- */
-void pchk_drop_ic_memtrap (void * p, void* addr) {
- PCLOCK();
- adl_splay_delete(&ICSplay, addr);
- PCUNLOCK();
-}
-
-/*
- * Function: pchk_reg_func()
- *
- * Description:
- * Register a set of function pointers with a MetaPool.
- */
-void
-pchk_reg_func (MetaPoolTy * MP, unsigned int num, void ** functable) {
- unsigned int index;
- unsigned int tag=0;
-
- for (index=0; index < num; ++index) {
- adl_splay_insert(&MP->Functions, functable[index], 1, &tag);
- }
-}
-
-/* Register a pool */
-/* The MPLoc is the location the pool wishes to store the metapool tag for */
-/* the pool PoolID is in at. */
-/* MP is the actual metapool. */
-void pchk_reg_pool(MetaPoolTy* MP, void* PoolID, void* MPLoc) {
- if(!MP) return;
- if(*(void**)MPLoc && *(void**)MPLoc != MP) {
- if(do_fail) poolcheckfail("reg_pool: Pool in 2 MP (inference bug a): ", (unsigned)*(void**)MPLoc, (void*)__builtin_return_address(0));
- if(do_fail) poolcheckfail("reg_pool: Pool in 2 MP (inference bug b): ", (unsigned) MP, (void*)__builtin_return_address(0));
- if(do_fail) poolcheckfail("reg_pool: Pool in 2 MP (inference bug c): ", (unsigned) PoolID, (void*)__builtin_return_address(0));
- }
-
- *(void**)MPLoc = (void*) MP;
-}
-
-/* A pool is deleted. free it's resources (necessary for correctness of checks) */
-void pchk_drop_pool(MetaPoolTy* MP, void* PoolID) {
- if(!MP) return;
- PCLOCK();
- adl_splay_delete_tag(&MP->Slabs, PoolID);
- PCUNLOCK();
-}
-
-/*
- * Function: poolcheckalign()
- *
- * Description:
- * Detremine whether the specified pointer is within the specified MetaPool
- * and whether it is at the specified offset from the beginning on an
- * object.
- */
-void
-poolcheckalign (MetaPoolTy* MP, void* addr, unsigned offset) {
- if (!pchk_ready || !MP) return;
-#if 0
- if (do_profile) pchk_profile(MP, __builtin_return_address(0));
-#endif
- ++stat_poolcheck;
- PCLOCK();
- void* S = addr;
- unsigned len = 0;
- int t = adl_splay_retrieve(&MP->Objs, &S, &len, 0);
- PCUNLOCK();
- if ((t) && ((addr - S) == offset))
- return;
- if(do_fail) poolcheckfail ("poolcheckalign failure: ", (unsigned)addr, (void*)__builtin_return_address(0));
-}
-
-/*
- * Function: poolcheckalign_i()
- *
- * Description:
- * This is the same as poolcheckalign(), but does not fail if an object cannot
- * be found. This is useful for checking incomplete/unknown nodes.
- */
-void
-poolcheckalign_i (MetaPoolTy* MP, void* addr, unsigned offset) {
- if (!pchk_ready || !MP) return;
-#if 0
- if (do_profile) pchk_profile(MP, __builtin_return_address(0));
-#endif
- ++stat_poolcheck;
- PCLOCK();
- void* S = addr;
- unsigned len = 0;
- volatile int t = adl_splay_retrieve(&MP->Objs, &S, &len, 0);
- PCUNLOCK();
- if (t) {
- if ((addr - S) == offset)
- return;
- else
- if (do_fail) poolcheckfail ("poolcheckalign_i failure: ", (unsigned)addr, (void*)__builtin_return_address(0));
- }
- return;
-}
-
-/* check that addr exists in pool MP */
-void poolcheck(MetaPoolTy* MP, void* addr) {
- if (!pchk_ready || !MP) return;
-#if 0
- if (do_profile) pchk_profile(MP, __builtin_return_address(0));
-#endif
- ++stat_poolcheck;
- PCLOCK();
- int t = adl_splay_find(&MP->Objs, addr);
- PCUNLOCK();
- if (t)
- return;
- if(do_fail) poolcheckfail ("poolcheck failure: ", (unsigned)addr, (void*)__builtin_return_address(0));
-}
-
-/*
- * Function: poolcheck_i()
- *
- * Description:
- * Same as poolcheck(), but does not fail if the pointer is not found. This is
- * useful for checking incomplete/unknown nodes.
- */
-void poolcheck_i (MetaPoolTy* MP, void* addr) {
- if (!pchk_ready || !MP) return;
-#if 0
- if (do_profile) pchk_profile(MP, __builtin_return_address(0));
-#endif
- ++stat_poolcheck;
- PCLOCK();
- volatile int t = adl_splay_find(&MP->Objs, addr);
- PCUNLOCK();
- return;
-}
-
-/* check that src and dest are same obj or slab */
-void poolcheckarray(MetaPoolTy* MP, void* src, void* dest) {
- if (!pchk_ready || !MP) return;
-#if 0
- if (do_profile) pchk_profile(MP, __builtin_return_address(0));
-#endif
- ++stat_poolcheckarray;
- void* S = src;
- void* D = dest;
- PCLOCK();
- /* try objs */
- adl_splay_retrieve(&MP->Objs, &S, 0, 0);
- adl_splay_retrieve(&MP->Objs, &D, 0, 0);
- PCUNLOCK();
- if (S == D)
- return;
- if(do_fail) poolcheckfail ("poolcheck failure: ", (unsigned)src, (void*)__builtin_return_address(0));
-}
-
-/* check that src and dest are same obj or slab */
-/* if src and dest do not exist in the pool, pass */
-void poolcheckarray_i(MetaPoolTy* MP, void* src, void* dest) {
- if (!pchk_ready || !MP) return;
-#if 0
- if (do_profile) pchk_profile(MP, __builtin_return_address(0));
-#endif
- ++stat_poolcheckarray_i;
- /* try slabs first */
- void* S = src;
- void* D = dest;
- PCLOCK();
-
- /* try objs */
- int fs = adl_splay_retrieve(&MP->Objs, &S, 0, 0);
- int fd = adl_splay_retrieve(&MP->Objs, &D, 0, 0);
- PCUNLOCK();
- if (S == D)
- return;
- if (fs || fd) { /*fail if we found one but not the other*/
- if(do_fail) poolcheckfail ("poolcheck failure: ", (unsigned)src, (void*)__builtin_return_address(0));
- return;
- }
- return; /*default is to pass*/
-}
-
-/*
- * Function: pchk_iccheck()
- *
- * Description:
- * Determine whether the given pointer points to the beginning of an Interrupt
- * Context.
- */
-void
-pchk_iccheck (void * addr) {
- if (!pchk_ready) return;
-
- /* try objs */
- void* S = addr;
- unsigned len = 0;
- PCLOCK();
- int fs = adl_splay_retrieve(&ICSplay, &S, &len, 0);
- PCUNLOCK();
- if (fs && (S == addr)) {
- return;
- }
-
- if (do_fail) poolcheckfail("iccheck failure: ", (unsigned) addr, (void*)__builtin_return_address(0));
- return;
-}
-
-const unsigned InvalidUpper = 4096;
-const unsigned InvalidLower = 0x03;
-
-
-/* if src is an out of object pointer, get the original value */
-void* pchk_getActualValue(MetaPoolTy* MP, void* src) {
- if (!pchk_ready || !MP || !use_oob) return src;
- if ((unsigned)src <= InvalidLower) return src;
- void* tag = 0;
- /* outside rewrite zone */
- if ((unsigned)src & ~(InvalidUpper - 1)) return src;
- PCLOCK();
- if (adl_splay_retrieve(&MP->OOB, &src, 0, &tag)) {
- PCUNLOCK();
- return tag;
- }
- PCUNLOCK();
- if(do_fail) poolcheckfail("GetActualValue failure: ", (unsigned) src, (void*)__builtin_return_address(0));
- return tag;
-}
-
-/*
- * Function: getBounds()
- *
- * Description:
- * Get the bounds associated with this object in the specified metapool.
- *
- * Return value:
- * If the node is found in the pool, it returns the bounds relative to
- * *src* (NOT the beginning of the object).
- * If the node is not found in the pool, it returns 0x00000000.
- * If the pool is not yet pchk_ready, it returns 0xffffffff
- */
-struct node {
- void* left;
- void* right;
- char* key;
- char* end;
- void* tag;
-};
-
-#define USERSPACE 0xC0000000
-
-struct node zero_page = {0, 0, 0, (char *)4095, 0};
-struct node not_found = {0, 0, 0, (char *)0x00000000, 0};
-struct node found = {0, 0, 0, (char *)0xffffffff, 0};
-struct node userspace = {0, 0, 0, (char* )USERSPACE, 0};
-
-void * getBegin (void * node) {
- return ((struct node *)(node))->key;
-}
-
-void * getEnd (void * node) {
- return ((struct node *)(node))->end;
-}
-
-void* getBounds(MetaPoolTy* MP, void* src) {
- if (!pchk_ready || !MP) return &found;
-#if 0
- if (do_profile) pchk_profile(MP, __builtin_return_address(0));
-#endif
- ++stat_boundscheck;
- /* first check for user space */
- if (src < USERSPACE) return &userspace;
-
- /* try objs */
- void* S = src;
- unsigned len = 0;
- PCLOCK();
- int fs = adl_splay_retrieve(&MP->Objs, &S, &len, 0);
- if (fs) {
- PCUNLOCK();
- return (MP->Objs);
- }
-
- PCUNLOCK();
-
- /*
- * If the source pointer is within the first page of memory, return the zero
- * page.
- */
- if (src < 4096)
- return &zero_page;
-
- /* Return that the object was not found */
- return ¬_found;
-}
-
-/*
- * Function: getBounds_i()
- *
- * Description:
- * Get the bounds associated with this object in the specified metapool.
- *
- * Return value:
- * If the node is found in the pool, it returns the bounds.
- * If the node is not found in the pool, it returns 0xffffffff.
- * If the pool is not yet pchk_ready, it returns 0xffffffff
- */
-void* getBounds_i(MetaPoolTy* MP, void* src) {
- if (!pchk_ready || !MP) return &found;
- ++stat_boundscheck;
- /* Try fail cache first */
- PCLOCK();
-#if 0
- int i = isInCache(MP, src);
- if (i) {
- mtfCache(MP, i);
- PCUNLOCK();
- return &found;
- }
-#endif
-#if 1
- {
- unsigned int index = MP->cindex;
- unsigned int cindex = MP->cindex;
- do
- {
- if ((MP->start[index] <= src) &&
- (MP->start[index]+MP->length[index] >= src))
- return MP->cache[index];
- index = (index + 1) & 3;
- } while (index != cindex);
- }
-#endif
- /* try objs */
- void* S = src;
- unsigned len = 0;
-#if 0
- PCLOCK2();
-#endif
- long long tsc1, tsc2;
- if (do_profile) tsc1 = llva_save_tsc();
- int fs = adl_splay_retrieve(&MP->Objs, &S, &len, 0);
- if (do_profile) tsc2 = llva_save_tsc();
- if (do_profile) pchk_profile(MP, __builtin_return_address(0), (long)(tsc2 - tsc1));
- if (fs) {
-#if 1
- unsigned int index = MP->cindex;
- MP->start[index] = S;
- MP->length[index] = len;
- MP->cache[index] = MP->Objs;
- MP->cindex = (index+1) & 3u;
-#endif
- PCUNLOCK();
- return MP->Objs;
- }
-
- PCUNLOCK();
-
- /*
- * If the source pointer is within the first page of memory, return the zero
- * page.
- */
- if (src < 4096)
- return &zero_page;
-
- return &found;
-}
-
-char* invalidptr = 0;
-
-/*
- * Function: boundscheck()
- *
- * Description:
- * Perform a precise array bounds check on source and result. If the result
- * is out of range for the array, return 0x1 so that getactualvalue() will
- * know that the pointer is bad and should not be dereferenced.
- */
-void* pchk_bounds(MetaPoolTy* MP, void* src, void* dest) {
- if (!pchk_ready || !MP) return dest;
-#if 0
- if (do_profile) pchk_profile(MP, __builtin_return_address(0));
-#endif
- ++stat_boundscheck;
- /* try objs */
- void* S = src;
- unsigned len = 0;
- PCLOCK();
- int fs = adl_splay_retrieve(&MP->Objs, &S, &len, 0);
- PCUNLOCK();
- if ((fs) && S <= dest && ((char*)S + len) > (char*)dest )
- return dest;
- else if (fs) {
- if (!use_oob) {
- if(do_fail) poolcheckfail ("boundscheck failure 1", (unsigned)src, (void*)__builtin_return_address(0));
- return dest;
- }
- PCLOCK2();
- if (invalidptr == 0) invalidptr = (unsigned char*)InvalidLower;
- ++invalidptr;
- void* P = invalidptr;
- PCUNLOCK();
- if ((unsigned)P & ~(InvalidUpper - 1)) {
- if(do_fail) poolcheckfail("poolcheck failure: out of rewrite ptrs", 0, (void*)__builtin_return_address(0));
- return dest;
- }
- if(do_fail) poolcheckinfo2("Returning oob pointer of ", (int)P, __builtin_return_address(0));
- PCLOCK2();
- adl_splay_insert(&MP->OOB, P, 1, dest);
- PCUNLOCK()
- return P;
- }
-
- /*
- * The node is not found or is not within bounds; fail!
- */
- if(do_fail) poolcheckfail ("boundscheck failure 2", (unsigned)src, (void*)__builtin_return_address(0));
- return dest;
-}
-
-/*
- * Function: uiboundscheck()
- *
- * Description:
- * Perform a precise array bounds check on source and result. If the result
- * is out of range for the array, return a sentinel so that getactualvalue()
- * will know that the pointer is bad and should not be dereferenced.
- *
- * This version differs from boundscheck() in that it does not generate a
- * poolcheck failure if the source node cannot be found within the MetaPool.
- */
-void* pchk_bounds_i(MetaPoolTy* MP, void* src, void* dest) {
- if (!pchk_ready || !MP) return dest;
-#if 0
- if (do_profile) pchk_profile(MP, __builtin_return_address(0));
-#endif
- ++stat_boundscheck_i;
- /* try fail cache */
- PCLOCK();
- int i = isInCache(MP, src);
- if (i) {
- mtfCache(MP, i);
- PCUNLOCK();
- return dest;
- }
- /* try objs */
- void* S = src;
- unsigned len = 0;
- unsigned int tag;
- int fs = adl_splay_retrieve(&MP->Objs, &S, &len, &tag);
- if ((fs) && (S <= dest) && (((unsigned char*)S + len) > (unsigned char*)dest)) {
- PCUNLOCK();
- return dest;
- }
- else if (fs) {
- if (!use_oob) {
- PCUNLOCK();
-#if 0
- if(do_fail) poolcheckfail ("uiboundscheck failure 1", (unsigned)S, len);
- if(do_fail) poolcheckfail ("uiboundscheck failure 2", (unsigned)S, tag);
-#endif
- if (do_fail) poolcheckfail ("uiboundscheck failure 3", (unsigned)dest, (void*)__builtin_return_address(0));
- return dest;
- }
- if (invalidptr == 0) invalidptr = (unsigned char*)0x03;
- ++invalidptr;
- void* P = invalidptr;
- if ((unsigned)P & ~(InvalidUpper - 1)) {
- PCUNLOCK();
- if(do_fail) poolcheckfail("poolcheck failure: out of rewrite ptrs", 0, (void*)__builtin_return_address(0));
- return dest;
- }
- adl_splay_insert(&MP->OOB, P, 1, dest);
- PCUNLOCK();
- return P;
- }
-
- /*
- * The node is not found or is not within bounds; pass!
- */
- int nn = insertCache(MP, src);
- mtfCache(MP, nn);
- PCUNLOCK();
- return dest;
-}
-
-void funccheck_g (MetaPoolTy * MP, void * f) {
- void* S = f;
- unsigned len = 0;
-
- PCLOCK();
- int fs = adl_splay_retrieve(&MP->Functions, &S, &len, 0);
- PCUNLOCK();
- if (fs)
- return;
-
- if (do_fail) poolcheckfail ("funccheck_g failed", f, (void*)__builtin_return_address(0));
-}
-
-void pchk_ind_fail(void * f) {
-#if 0
- if (do_fail) poolcheckfail("indirect call failure", f, (void*)__builtin_return_address(0));
-#else
- printk ("<0> LLVA: pchk_ind_fail: pc=%x, f=%x\n", f, (void*)(__builtin_return_address(0)));
-#endif
-}
-
diff --git a/safecode/runtime/KPoolCheck/PoolCheck.h b/safecode/runtime/KPoolCheck/PoolCheck.h
deleted file mode 100755
index ad3b1d7..0000000
--- a/safecode/runtime/KPoolCheck/PoolCheck.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*===- PoolCheck.h - Pool check runtime interface file --------------------===*/
-/* */
-/* The LLVM Compiler Infrastructure */
-/* */
-/* This file was developed by the LLVM research group and is distributed */
-/* under the University of Illinois Open Source License. See LICENSE.TXT for */
-/* details. */
-/* */
-/*===----------------------------------------------------------------------===*/
-/* */
-/* */
-/*===----------------------------------------------------------------------===*/
-
-#ifndef POOLCHECK_RUNTIME_H
-#define POOLCHECK_RUNTIME_H
-
-typedef struct MetaPoolTy {
- /* A splay of Pools, useful for registration tracking */
- void* Slabs;
-
- /* A splay for registering global objects and heap objects */
- void* Objs;
-
- /* A splay for registering function pointers */
- void * Functions;
-
- /* A splay of rewritten Obj Pointers */
- void* OOB;
-
- /* Next invalid Ptr for rewriting */
- void* profile;
-
- /*cache space */
- void* cache0;
- void* cache1;
- void* cache2;
- void* cache3;
-
-#if 1
- unsigned int cindex;
- unsigned int start[4];
- unsigned int length[4];
- void * cache[4];
-#endif
-
-} MetaPoolTy;
-
-typedef struct funccache {
- unsigned int index;
- void * cache[4];
-} funccache;
-
-#ifdef __cpluscplus
-extern "C" {
-#endif
- /* initialize library */
- void pchk_init(void);
-
- /* Registration functions */
- /* These are written such that a weaker version (without MP) can be */
- /* inserted in the kernel by the programer and we can trivial rewrite them */
- /* to include the metapool */
- void pchk_reg_slab(MetaPoolTy* MP, void* PoolID, void* addr, unsigned len);
- void pchk_drop_slab(MetaPoolTy* MP, void* PoolID, void* addr);
- void pchk_reg_obj(MetaPoolTy* MP, void* addr, unsigned len);
- void pchk_drop_obj(MetaPoolTy* MP, void* addr);
- void pchk_reg_pool(MetaPoolTy* MP, void* PoolID, void* MPLoc);
- void pchk_drop_pool(MetaPoolTy* MP, void* PoolID);
-
- /* check that addr exists in pool MP */
- void poolcheck(MetaPoolTy* MP, void* addr);
-
- /* check that src and dest are same obj or slab */
- void poolcheckarray(MetaPoolTy* MP, void* src, void* dest);
-
- /* check that src and dest are same obj or slab */
- /* if src and dest do not exist in the pool, pass */
- void poolcheckarray_i(MetaPoolTy* MP, void* src, void* dest);
-
- /* if src is an out of object pointer, get the original value */
- void* pchk_getActualValue(MetaPoolTy* MP, void* src);
-
- /* check bounds and return result ptr, which may have been rewritten */
- void* pchk_bounds(MetaPoolTy* MP, void* src, void* dest);
- void* pchk_bounds_i(MetaPoolTy* MP, void* src, void* dest);
-
- void * exactcheck(int a, int b, void * result) __attribute__ ((weak));
- void * exactcheck2(signed char *base, signed char *result, unsigned size) __attribute__ ((weak));
- void * exactcheck2a(signed char *base, signed char *result, unsigned size) __attribute__ ((weak));
- void * exactcheck3(signed char *base, signed char *result, signed char * end)__attribute__ ((weak));
-
- void funccheck (unsigned num, void *f, void *t1, void *t2, void *t3, void *t4, void * t5, void * t6) __attribute__ ((weak));
- void funccheck_t (unsigned num, void * f, void ** table) __attribute__ ((weak));
- void funccheck_g (MetaPoolTy * MP, void * f) __attribute__ ((weak));
- void pchk_reg_ic (int s, int a, int b, int c, int d, int e, int f, void* ad);
- void pchk_drop_ic (void* addr);
- void pchk_iccheck (void * addr);
- void * getBegin (void * node) __attribute__ ((weak));
- void * getEnd (void * node) __attribute__ ((weak));
-
- void pchk_profile(MetaPoolTy* MP, void* pc, long time);
-
-#ifdef __cpluscplus
-}
-#endif
-
-#endif
diff --git a/safecode/runtime/KPoolCheck/PoolProfile.c b/safecode/runtime/KPoolCheck/PoolProfile.c
deleted file mode 100755
index cff43af..0000000
--- a/safecode/runtime/KPoolCheck/PoolProfile.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/* Profiling support:
-
- Each Metapool contains a pointer to a profile tree. this tree
- tracks profile call site and frequency A global tree is also
- maintained that tracks all metapools.
-*/
-
-#include "PoolCheck.h"
-#include "adl_splay.h"
-
-extern int printk(const char *fmt, ...);
-
-static void* allmp = 0;
-int profile_pause = 1;
-
-void pchk_profile(MetaPoolTy* MP, void* pc, long time) {
- if (profile_pause) return;
- if (!MP) return;
-
- if (!adl_splay_retrieve (&allmp, MP, 0, 0))
- adl_splay_insert(&allmp, MP, 1, 0);
-
- void* key = pc;
- unsigned tag=0;
- unsigned len=0;
-
- if (adl_splay_retrieve(&MP->profile, &key, &len, &tag)) {
- tag += time;
- adl_splay_insert(&MP->profile, key, len, tag);
- } else {
- adl_splay_insert(&MP->profile, key, 1, tag);
- }
-}
-
-static void * thepool;
-
-void print_item(void* p, unsigned l, void* t) {
- printk("(0x%x, 0x%x, %d)\n", thepool, p, (unsigned) t);
-}
-
-void print_pool(void* p, unsigned l, void* t) {
- thepool = p;
- adl_splay_foreach(&(((MetaPoolTy*)p)->profile), print_item);
-}
-
-void pchk_profile_print() {
- int old = profile_pause;
- profile_pause = 1;
-
-printk ("LLVA:Printing Profile:\n");
- adl_splay_foreach(&allmp, print_pool);
-
- profile_pause = old;
-}
-
diff --git a/safecode/runtime/KPoolCheck/PoolSystem.h b/safecode/runtime/KPoolCheck/PoolSystem.h
deleted file mode 100755
index 0c0fcac..0000000
--- a/safecode/runtime/KPoolCheck/PoolSystem.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*===- PoolSystem.h - Pool check runtime interface to the system ----------===*/
-/* */
-/* The LLVM Compiler Infrastructure */
-/* */
-/* This file was developed by the LLVM research group and is distributed */
-/* under the University of Illinois Open Source License. See LICENSE.TXT for */
-/* details. */
-/* */
-/*===----------------------------------------------------------------------===*/
-/* */
-/* */
-/*===----------------------------------------------------------------------===*/
-
-#ifndef POOLSYSTEM_RUNTIME_H
-#define POOLSYSTEM_RUNTIME_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
- /* Functions that need to be provided by the pool allocation run-time */
- void poolcheckfail (const char * msg, int, void*);
- void poolcheckfatal (const char * msg, int);
- void poolcheckinfo (const char * msg, int);
- void poolcheckinfo2 (const char * msg, int, int);
- void * poolcheckmalloc (unsigned int size);
- void printpoolinfo (void *Pool);
- void poolcheckglobals ();
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/safecode/runtime/KPoolCheck/Statistics.c b/safecode/runtime/KPoolCheck/Statistics.c
deleted file mode 100755
index 98e74cf..0000000
--- a/safecode/runtime/KPoolCheck/Statistics.c
+++ /dev/null
@@ -1,54 +0,0 @@
-/*===- Stats.cpp - Statistics held by the runtime -------------------------===*/
-/* */
-/* The LLVM Compiler Infrastructure */
-/* */
-/* This file was developed by the LLVM research group and is distributed */
-/* under the University of Illinois Open Source License. See LICENSE.TXT for */
-/* details. */
-/* */
-/*===----------------------------------------------------------------------===*/
-/* */
-/* This file implements functions that can be used to hold statistics */
-/* information */
-/* */
-/*===----------------------------------------------------------------------===*/
-
-/* The number of stack to heap promotions executed dynamically */
-static int stack_promotes = 0;
-
-int stat_exactcheck = 0;
-int stat_exactcheck2 = 0;
-int stat_exactcheck3 = 0;
-
-extern int stat_poolcheck;
-extern int stat_poolcheckarray;
-extern int stat_poolcheckarray_i;
-extern int stat_boundscheck;
-extern int stat_boundscheck_i;
-extern unsigned int externallocs;
-extern unsigned int allallocs;
-
-void
-stackpromote()
-{
- ++stack_promotes;
- return;
-}
-
-int
-getstackpromotes()
-{
- poolcheckinfo ("LLVA: getstackpromotes", stack_promotes);
- poolcheckinfo ("LLVA: stat_exactcheck", stat_exactcheck);
- poolcheckinfo ("LLVA: stat_exactcheck2", stat_exactcheck2);
- poolcheckinfo ("LLVA: stat_exactcheck3", stat_exactcheck3);
- poolcheckinfo ("LLVA: stat_poolcheck", stat_poolcheck);
- poolcheckinfo ("LLVA: stat_poolcheckarray", stat_poolcheckarray);
- poolcheckinfo ("LLVA: stat_poolcheckarray_i", stat_poolcheckarray_i);
- poolcheckinfo ("LLVA: stat_boundscheck", stat_boundscheck);
- poolcheckinfo ("LLVA: stat_boundscheck_i", stat_boundscheck_i);
- poolcheckinfo ("LLVA: external allocs", externallocs);
- poolcheckinfo ("LLVA: all allocs", allallocs);
- return stack_promotes;
-}
-
diff --git a/safecode/runtime/KPoolCheck/adl_rbtree.c b/safecode/runtime/KPoolCheck/adl_rbtree.c
deleted file mode 100755
index 6174a84..0000000
--- a/safecode/runtime/KPoolCheck/adl_rbtree.c
+++ /dev/null
@@ -1,265 +0,0 @@
-#include "adl_splay.h"
-
-#ifdef USE_RB
-
-#include "rb_kernel.h"
-#include "PoolSystem.h"
-
-typedef struct tree_node Tree;
-struct tree_node {
- rb_node_t node;
- char* key;
- char* end;
- void* tag;
-};
-
-
-/* Memory management functions */
-
-static Tree* freelist = 0;
-static void* (*ext_alloc)(unsigned) = 0;
-unsigned int externallocs = 0;
-unsigned int allallocs = 0;
-
-static Tree initmem[1024];
-static int use = 0;
-
-static void *
-internal_malloc (unsigned int size)
-{
- static unsigned char * page = 0;
- static unsigned char * loc = 0;
- unsigned char * retvalue;
-
- if (size > 4096)
- poolcheckfatal ("LLVA: internal_malloc: Size", size);
-
- /*
- * Allocate a new page if we've never had a page or there isn't any room
- * in the current page.
- */
- if (!page)
- {
- loc = page = ext_alloc (0);
- ++externallocs;
- }
-
- if ((loc+size) > (page + 4096))
- {
- loc = page = ext_alloc (0);
- ++externallocs;
- }
-
- /*
- * Allocate the space and return a pointer to it.
- */
- retvalue = loc;
- loc += size;
- return retvalue;
-}
-
-static inline Tree* tmalloc() {
- ++allallocs;
- if(freelist) {
- Tree* t = freelist;
- freelist = (Tree*)freelist->key;
- return t;
- } else if(use < 1024) {
- ++use;
- return &initmem[use-1];
- } else {
- Tree * tmp = internal_malloc(sizeof(Tree));
- if (!tmp)
- poolcheckfatal ("LLVA: tmalloc: Failed to allocate\n", 0);
- return (Tree*) tmp;
- }
-}
-
-static inline void tfree(Tree* t) {
- t->key = (char*)freelist;
- freelist = t;
-}
-
-
-#define key_lt(_key, _t) (((char*)_key < (char*)_t->key))
-
-#define key_gt(_key, _t) (((char*)_key > (char*)_t->end))
-
-static Tree *my_search(rb_root_t *root, char *k)
-{
- rb_node_t *node = root->rb_node;
-
- while (node) {
- Tree* data = rb_entry(node, Tree, node);
-
- if (key_lt(k,data))
- node = node->rb_left;
- else if (key_gt(k,data))
- node = node->rb_right;
- else
- return data;
- }
- return 0;
-}
-
-static int my_insert(rb_root_t *root, char* key, unsigned len, void* tag)
-{
- Tree* data = 0;
- rb_node_t **new = &(root->rb_node), *parent = 0;
-
- /* Figure out where to put new node */
- while (*new) {
- Tree* this = rb_entry(*new, Tree, node);
-
- parent = *new;
- if (key_lt(key, this))
- new = &((*new)->rb_left);
- else if (key_gt(key, this))
- new = &((*new)->rb_right);
- else
- return 0;
- }
-
- data = tmalloc();
- data->key = key;
- data->end = key + (len - 1);
- data->tag = tag;
-
- /* Add new node and rebalance tree. */
- rb_link_node(&data->node, parent, new);
- rb_insert_color(&data->node, root);
-
- return 1;
-}
-
-static void my_delete(rb_root_t* root, char* k) {
- Tree *data = my_search(root, k);
-
- if (data) {
- rb_erase(&data->node, root);
- tfree(data);
- }
-}
-
-static int count(rb_node_t* t) {
- if (t)
- return 1 + count(t->rb_left) + count(t->rb_right);
- return 0;
-}
-
-/* return any node with the matching tag */
-static Tree* find_tag(rb_node_t* n, void* tag) {
- if (n) {
- Tree *t = rb_entry(n, Tree, node);
- if (t->tag == tag) return t;
- if ((t = find_tag(n->rb_left, tag))) return t;
- if ((t = find_tag(n->rb_right, tag))) return t;
- }
- return 0;
-}
-
-/* interface */
-
-void adl_splay_insert(void** tree, void* key, unsigned len, void* tag)
-{
- my_insert((rb_root_t*)tree, (char*)key, len, tag);
-}
-
-void adl_splay_delete(void** tree, void* key)
-{
- my_delete((rb_root_t*)tree, (char*)key);
-}
-
-void adl_splay_delete_tag(void** tree, void* tag) {
- rb_root_t* t = (rb_root_t*)tree;
- Tree* n = find_tag(t->rb_node, tag);
- while (n) {
- my_delete(t, n->key);
- n = find_tag(t->rb_node, tag);
- }
-}
-
-int adl_splay_find(void** tree, void* key) {
- Tree* t = my_search((rb_root_t*)tree, (char*)key);
- return (t &&
- !key_lt(key, t) &&
- !key_gt(key, t));
-}
-
-int adl_splay_retrieve(void** tree, void** key, unsigned* len, void** tag) {
- void* k = *key;
- Tree* t = my_search((rb_root_t*)tree, (char*)k);
- if (t &&
- !key_lt(k, t) &&
- !key_gt(k, t)) {
- *key = t->key;
- if (len) *len = (t->end - t->key) + 1;
- if (tag) *tag = t->tag;
- return 1;
- }
- return 0;
-}
-
-int adl_splay_size(void** tree) {
- return (count(((rb_root_t*)tree)->rb_node));
-}
-
-void* adl_splay_any(void** tree) {
- if (((rb_root_t*)tree)->rb_node) {
- Tree *t = rb_entry(((rb_root_t*)tree)->rb_node, Tree, node);
- return t->key;
- }
- return 0;
-}
-
-void adl_splay_libinit(void* (nodealloc)(unsigned) ) {
- ext_alloc = nodealloc;
-}
-
-void adl_splay_libfini(void (nodefree)(void*) ) {
- while (freelist) {
- Tree* n = (Tree*)freelist->key;
- nodefree(freelist);
- freelist = n;
- }
-}
-
-
-#ifdef TEST_TREE
-#include <stdio.h>
-#include <stdlib.h>
-
-int main() {
- adl_splay_libinit((void* (*)(int))malloc);
- void* t = 0;
- long x;
- for (x = 0; x < 100; ++x) {
- adl_splay_insert(&t, (void*)x, 10, 0);
- }
-
- printf("Size after 100 inserts of size 10 (overlap): %d\n", adl_splay_size(&t));
-
- for (x = 0; x < 100; ++x) {
- int f = adl_splay_find(&t, (void*)x);
- if (!f) printf("Failed find!\n");
- }
- for (x = 0; x < 100; x += 20) {
- int f = adl_splay_find(&t, (void*)x);
- if (!f) printf("Failed find!\n");
- }
-
- for (x = 0; x < 100; ++x) {
- adl_splay_delete(&t, (void*)x);
- }
-
- printf("Size should be 0: %d\n", adl_splay_size(&t));
- return 0;
-}
-
-void poolcheckfatal (const char * msg, int x) {
- printf("%s %d\n", msg, x);
-}
-
-#endif
-
-#endif
diff --git a/safecode/runtime/KPoolCheck/adl_splay.c b/safecode/runtime/KPoolCheck/adl_splay.c
deleted file mode 100755
index b536d31..0000000
--- a/safecode/runtime/KPoolCheck/adl_splay.c
+++ /dev/null
@@ -1,352 +0,0 @@
-#include "adl_splay.h"
-
-#ifndef USE_RB
-
-#include "PoolSystem.h"
-
-typedef struct tree_node Tree;
-struct tree_node {
- Tree* left;
- Tree* right;
- char* key;
- char* end;
- void* tag;
-};
-
-/* Memory management functions */
-
-static Tree* freelist = 0;
-static void* (*ext_alloc)(unsigned) = 0;
-unsigned int externallocs = 0;
-unsigned int allallocs = 0;
-
-static Tree initmem[1024];
-static int use = 0;
-
-static void *
-internal_malloc (unsigned int size)
-{
- static unsigned char * page = 0;
- static unsigned char * loc = 0;
- unsigned char * retvalue;
-
- if (size > 4096)
- poolcheckfatal ("LLVA: internal_malloc: Size", size);
-
- /*
- * Allocate a new page if we've never had a page or there isn't any room
- * in the current page.
- */
- if (!page)
- {
- loc = page = ext_alloc (0);
- ++externallocs;
- }
-
- if ((loc+size) > (page + 4096))
- {
- loc = page = ext_alloc (0);
- ++externallocs;
- }
-
- /*
- * Allocate the space and return a pointer to it.
- */
- retvalue = loc;
- loc += size;
- return retvalue;
-}
-
-static inline Tree* tmalloc() {
- ++allallocs;
- if(freelist) {
- Tree* t = freelist;
- freelist = freelist->left;
- return t;
- } else if(use < 1024) {
- ++use;
- return &initmem[use-1];
- } else {
- Tree * tmp = internal_malloc(sizeof(Tree));
- if (!tmp)
- poolcheckfatal ("LLVA: tmalloc: Failed to allocate\n", 0);
- return (Tree*) tmp;
- }
-}
-
-static inline void tfree(Tree* t) {
- t->left = freelist;
- freelist = t;
-}
-
-
-#define key_lt(_key, _t) (((char*)_key < (char*)_t->key))
-
-#define key_gt(_key, _t) (((char*)_key > (char*)_t->end))
-
-
-static inline Tree* rotate_right(Tree* p) {
- Tree* x = p->left;
- p->left = x->right;
- x->right = p;
- return x;
-}
-
-static inline Tree* rotate_left(Tree* p) {
- Tree* x = p->right;
- p->right = x->left;
- x->left = p;
- return x;
-}
-
-/* This function by D. Sleator <sleator@cs.cmu.edu> */
-static Tree* splay (Tree * t, char* key) {
- Tree N, *l, *r, *y;
- if (t == 0) return t;
- N.left = N.right = 0;
- l = r = &N;
-
- while(1) {
- if (key_lt(key, t)) {
- if (t->left == 0) break;
- if (key_lt(key, t->left)) {
- y = t->left; /* rotate right */
- t->left = y->right;
- y->right = t;
- t = y;
- if (t->left == 0) break;
- }
- r->left = t; /* link right */
- r = t;
- t = t->left;
- } else if (key_gt(key, t)) {
- if (t->right == 0) break;
- if (key_gt(key, t->right)) {
- y = t->right; /* rotate left */
- t->right = y->left;
- y->left = t;
- t = y;
- if (t->right == 0) break;
- }
- l->right = t; /* link left */
- l = t;
- t = t->right;
- } else {
- break;
- }
- }
- l->right = t->left; /* assemble */
- r->left = t->right;
- t->left = N.right;
- t->right = N.left;
- return t;
-}
-
-/* My version, needs testing */
-static Tree* my_splay(Tree* t, char* key) {
- if (!t) return t;
-
- while (1) {
- if (key_lt(key, t)) {
- if (!t->left) return t;
- else if (key_lt(key, t->left))
- t = rotate_right(rotate_right(t));
- else if (key_gt(key, t->left)) {
- t->left = rotate_left(t->left);
- t = rotate_right(t);
- } else
- return rotate_right(t);
- } else if (key_gt(key, t)) {
- if (!t->right) return t;
- else if (key_gt(key, t->right))
- t = rotate_left(rotate_left(t));
- else if (key_lt(key, t->right)) {
- t->right = rotate_right(t->right);
- t = rotate_left(t);
- } else
- return rotate_left(t);
- } else
- return t;
- }
-}
-
-static inline Tree* insert(Tree* t, char* key, unsigned len, void* tag) {
- Tree* n = 0;
- t = splay(t, key);
- if (t && !key_lt(key, t) && !key_gt(key, t)) {
- /* already in, so update the record. This could break
- the tree */
- t->key = key;
- t->end = t->key + (len - 1);
- t->tag = tag;
- return t;
- }
- n = tmalloc();
- n->key = key;
- n->end = key + (len - 1);
- n->tag = tag;
- n->right = n->left = 0;
- if (t) {
- if (key_lt(key, t)) {
- n->left = t->left;
- n->right = t;
- t->left = 0;
- } else {
- n->right = t->right;
- n->left = t;
- t->right = 0;
- }
- }
- return n;
-}
-
-static inline Tree* delete(Tree* t, char* key) {
- if (!t) return t;
- t = splay(t, key);
- if (!key_lt(key, t) && !key_gt(key, t)) {
- Tree* x = 0;
- if (!t->left)
- x = t->right;
- else {
- x = splay(t->left, key);
- x->right = t->right;
- }
- tfree(t);
- return x;
- }
- return t; /* not there */
-}
-
-static int count(Tree* t) {
- if (t)
- return 1 + count(t->left) + count(t->right);
- return 0;
-}
-
-/* return any node with the matching tag */
-static Tree* find_tag(Tree* t, void* tag) {
- if (t) {
- Tree* n = 0;
- if (t->tag == tag) return t;
- if ((n = find_tag(t->left, tag))) return n;
- if ((n = find_tag(t->right, tag))) return n;
- }
- return 0;
-}
-
-/* interface */
-
-void adl_splay_insert(void** tree, void* key, unsigned len, void* tag)
-{
- *(Tree**)tree = insert(*(Tree**)tree, (char*)key, len, tag);
-}
-
-void adl_splay_delete(void** tree, void* key)
-{
- *(Tree**)tree = delete(*(Tree**)tree, (char*)key);
-}
-
-void adl_splay_delete_tag(void** tree, void* tag) {
- Tree* t = *(Tree**)tree;
- Tree* n = find_tag(t, tag);
- while (n) {
- t = delete(t, n->key);
- n = find_tag(t, tag);
- }
- *(Tree**)tree = t;
-}
-
-int adl_splay_find(void** tree, void* key) {
- Tree* t = splay(*(Tree**)tree, (char*)key);
- *(Tree**)tree = t;
- return (t &&
- !key_lt(key, t) &&
- !key_gt(key, t));
-}
-
-int adl_splay_retrieve(void** tree, void** key, unsigned* len, void** tag) {
- void* k = *key;
- Tree* t = splay(*(Tree**)tree, (char*)k);
- *(Tree**)tree = t;
- if (t &&
- !key_lt(k, t) &&
- !key_gt(k, t)) {
- *key = t->key;
- if (len) *len = (t->end - t->key) + 1;
- if (tag) *tag = t->tag;
- return 1;
- }
- return 0;
-}
-
-int adl_splay_size(void** tree) {
- return (count(*(Tree**)tree));
-}
-
-void* adl_splay_any(void** tree) {
- if (*(Tree**)tree)
- return ((*(Tree**)tree)->key);
- return 0;
-}
-
-void adl_splay_libinit(void* (nodealloc)(unsigned) ) {
- ext_alloc = nodealloc;
-}
-
-void adl_splay_libfini(void (nodefree)(void*) ) {
- while (freelist) {
- Tree* n = freelist->left;
- nodefree(freelist);
- freelist = n;
- }
-}
-
-void adl_splay_foreach(void** tree, void (f)(void*, unsigned, void*)) {
- Tree* T = *(Tree**)tree;
- if (T) {
- f(T->key, (T->end - T->key) + 1, T->tag);
- adl_splay_foreach(&T->left, f);
- adl_splay_foreach(&T->right, f);
- }
-}
-
-
-#ifdef TEST_TREE
-#include <stdio.h>
-#include <stdlib.h>
-
-int main() {
- adl_splay_libinit((void* (*)(int))malloc);
- void* t = 0;
- long x;
- for (x = 0; x < 100; ++x) {
- adl_splay_insert(&t, (void*)x, 10, 0);
- }
-
- printf("Size after 100 inserts of size 10 (overlap): %d\n", adl_splay_size(&t));
-
- for (x = 0; x < 100; ++x) {
- int f = adl_splay_find(&t, (void*)x);
- if (!f) printf("Failed find!\n");
- }
- for (x = 0; x < 100; x += 20) {
- int f = adl_splay_find(&t, (void*)x);
- if (!f) printf("Failed find!\n");
- }
-
- for (x = 0; x < 100; ++x) {
- adl_splay_delete(&t, (void*)x);
- }
-
- printf("Size should be 0: %d\n", adl_splay_size(&t));
- return 0;
-}
-
-void poolcheckfatal (const char * msg, int x) {
- printf("%s %d\n", msg, x);
-}
-
-
-#endif
-
-#endif
diff --git a/safecode/runtime/KPoolCheck/adl_splay.h b/safecode/runtime/KPoolCheck/adl_splay.h
deleted file mode 100755
index 89e0417..0000000
--- a/safecode/runtime/KPoolCheck/adl_splay.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifdef __cpluscplus
-extern "C" {
-#endif
- extern void adl_splay_insert(void** tree, void* key, unsigned len, void* tag);
- extern void adl_splay_delete(void** tree, void* key);
- extern void adl_splay_delete_tag(void** tree, void* tag); /*expensive */
-
- extern int adl_splay_find(void** tree, void* key);
- extern int adl_splay_retrieve(void** tree, void** key, unsigned* len, void** tag);
- extern int adl_splay_size(void** tree);
- extern void* adl_splay_any(void** tree);
-
- extern void adl_splay_libinit(void* (nodealloc)(unsigned) );
- extern void adl_splay_libfini(void (nodefree)(void*) );
-
- extern void adl_splay_foreach(void** tree, void (f)(void*, unsigned, void*));
-
-#ifdef __cpluscplus
-}
-#endif
-
-/* #define USE_RB */
diff --git a/safecode/runtime/KPoolCheck/rb_kernel.h b/safecode/runtime/KPoolCheck/rb_kernel.h
deleted file mode 100755
index 10ca87e..0000000
--- a/safecode/runtime/KPoolCheck/rb_kernel.h
+++ /dev/null
@@ -1,300 +0,0 @@
-typedef struct rb_node_s
-{
- struct rb_node_s * rb_parent;
- int rb_color;
-#define RB_RED 0
-#define RB_BLACK 1
- struct rb_node_s * rb_right;
- struct rb_node_s * rb_left;
-}
- rb_node_t;
-
-typedef struct rb_root_s
-{
- struct rb_node_s * rb_node;
-}
- rb_root_t;
-
-#define RB_ROOT (rb_root_t) { NULL, }
-#define rb_entry(ptr, type, member) \
- ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
-
-static inline void rb_link_node(rb_node_t * node, rb_node_t * parent, rb_node_t ** rb_link)
-{
- node->rb_parent = parent;
- node->rb_color = RB_RED;
- node->rb_left = node->rb_right = 0;
-
- *rb_link = node;
-}
-
-static void __rb_rotate_left(rb_node_t * node, rb_root_t * root)
-{
- rb_node_t * right = node->rb_right;
-
- if ((node->rb_right = right->rb_left))
- right->rb_left->rb_parent = node;
- right->rb_left = node;
-
- if ((right->rb_parent = node->rb_parent))
- {
- if (node == node->rb_parent->rb_left)
- node->rb_parent->rb_left = right;
- else
- node->rb_parent->rb_right = right;
- }
- else
- root->rb_node = right;
- node->rb_parent = right;
-}
-
-static void __rb_rotate_right(rb_node_t * node, rb_root_t * root)
-{
- rb_node_t * left = node->rb_left;
-
- if ((node->rb_left = left->rb_right))
- left->rb_right->rb_parent = node;
- left->rb_right = node;
-
- if ((left->rb_parent = node->rb_parent))
- {
- if (node == node->rb_parent->rb_right)
- node->rb_parent->rb_right = left;
- else
- node->rb_parent->rb_left = left;
- }
- else
- root->rb_node = left;
- node->rb_parent = left;
-}
-
-static void rb_insert_color(rb_node_t * node, rb_root_t * root)
-{
- rb_node_t * parent, * gparent;
-
- while ((parent = node->rb_parent) && parent->rb_color == RB_RED)
- {
- gparent = parent->rb_parent;
-
- if (parent == gparent->rb_left)
- {
- {
- register rb_node_t * uncle = gparent->rb_right;
- if (uncle && uncle->rb_color == RB_RED)
- {
- uncle->rb_color = RB_BLACK;
- parent->rb_color = RB_BLACK;
- gparent->rb_color = RB_RED;
- node = gparent;
- continue;
- }
- }
-
- if (parent->rb_right == node)
- {
- register rb_node_t * tmp;
- __rb_rotate_left(parent, root);
- tmp = parent;
- parent = node;
- node = tmp;
- }
-
- parent->rb_color = RB_BLACK;
- gparent->rb_color = RB_RED;
- __rb_rotate_right(gparent, root);
- } else {
- {
- register rb_node_t * uncle = gparent->rb_left;
- if (uncle && uncle->rb_color == RB_RED)
- {
- uncle->rb_color = RB_BLACK;
- parent->rb_color = RB_BLACK;
- gparent->rb_color = RB_RED;
- node = gparent;
- continue;
- }
- }
-
- if (parent->rb_left == node)
- {
- register rb_node_t * tmp;
- __rb_rotate_right(parent, root);
- tmp = parent;
- parent = node;
- node = tmp;
- }
-
- parent->rb_color = RB_BLACK;
- gparent->rb_color = RB_RED;
- __rb_rotate_left(gparent, root);
- }
- }
-
- root->rb_node->rb_color = RB_BLACK;
-}
-
-static void __rb_erase_color(rb_node_t * node, rb_node_t * parent,
- rb_root_t * root)
-{
- rb_node_t * other;
-
- while ((!node || node->rb_color == RB_BLACK) && node != root->rb_node)
- {
- if (parent->rb_left == node)
- {
- other = parent->rb_right;
- if (other->rb_color == RB_RED)
- {
- other->rb_color = RB_BLACK;
- parent->rb_color = RB_RED;
- __rb_rotate_left(parent, root);
- other = parent->rb_right;
- }
- if ((!other->rb_left ||
- other->rb_left->rb_color == RB_BLACK)
- && (!other->rb_right ||
- other->rb_right->rb_color == RB_BLACK))
- {
- other->rb_color = RB_RED;
- node = parent;
- parent = node->rb_parent;
- }
- else
- {
- if (!other->rb_right ||
- other->rb_right->rb_color == RB_BLACK)
- {
- register rb_node_t * o_left;
- if ((o_left = other->rb_left))
- o_left->rb_color = RB_BLACK;
- other->rb_color = RB_RED;
- __rb_rotate_right(other, root);
- other = parent->rb_right;
- }
- other->rb_color = parent->rb_color;
- parent->rb_color = RB_BLACK;
- if (other->rb_right)
- other->rb_right->rb_color = RB_BLACK;
- __rb_rotate_left(parent, root);
- node = root->rb_node;
- break;
- }
- }
- else
- {
- other = parent->rb_left;
- if (other->rb_color == RB_RED)
- {
- other->rb_color = RB_BLACK;
- parent->rb_color = RB_RED;
- __rb_rotate_right(parent, root);
- other = parent->rb_left;
- }
- if ((!other->rb_left ||
- other->rb_left->rb_color == RB_BLACK)
- && (!other->rb_right ||
- other->rb_right->rb_color == RB_BLACK))
- {
- other->rb_color = RB_RED;
- node = parent;
- parent = node->rb_parent;
- }
- else
- {
- if (!other->rb_left ||
- other->rb_left->rb_color == RB_BLACK)
- {
- register rb_node_t * o_right;
- if ((o_right = other->rb_right))
- o_right->rb_color = RB_BLACK;
- other->rb_color = RB_RED;
- __rb_rotate_left(other, root);
- other = parent->rb_left;
- }
- other->rb_color = parent->rb_color;
- parent->rb_color = RB_BLACK;
- if (other->rb_left)
- other->rb_left->rb_color = RB_BLACK;
- __rb_rotate_right(parent, root);
- node = root->rb_node;
- break;
- }
- }
- }
- if (node)
- node->rb_color = RB_BLACK;
-}
-
-static void rb_erase(rb_node_t * node, rb_root_t * root)
-{
- rb_node_t * child, * parent;
- int color;
-
- if (!node->rb_left)
- child = node->rb_right;
- else if (!node->rb_right)
- child = node->rb_left;
- else
- {
- rb_node_t * old = node, * left;
-
- node = node->rb_right;
- while ((left = node->rb_left))
- node = left;
- child = node->rb_right;
- parent = node->rb_parent;
- color = node->rb_color;
-
- if (child)
- child->rb_parent = parent;
- if (parent)
- {
- if (parent->rb_left == node)
- parent->rb_left = child;
- else
- parent->rb_right = child;
- }
- else
- root->rb_node = child;
-
- if (node->rb_parent == old)
- parent = node;
- node->rb_parent = old->rb_parent;
- node->rb_color = old->rb_color;
- node->rb_right = old->rb_right;
- node->rb_left = old->rb_left;
-
- if (old->rb_parent)
- {
- if (old->rb_parent->rb_left == old)
- old->rb_parent->rb_left = node;
- else
- old->rb_parent->rb_right = node;
- } else
- root->rb_node = node;
-
- old->rb_left->rb_parent = node;
- if (old->rb_right)
- old->rb_right->rb_parent = node;
- goto color;
- }
-
- parent = node->rb_parent;
- color = node->rb_color;
-
- if (child)
- child->rb_parent = parent;
- if (parent)
- {
- if (parent->rb_left == node)
- parent->rb_left = child;
- else
- parent->rb_right = child;
- }
- else
- root->rb_node = child;
-
- color:
- if (color == RB_BLACK)
- __rb_erase_color(child, parent, root);
-}
diff --git a/safecode/runtime/KernelSafePoolAllocator/PageManager.cpp b/safecode/runtime/KernelSafePoolAllocator/PageManager.cpp
index 906aa6a..32e5643 100755
--- a/safecode/runtime/KernelSafePoolAllocator/PageManager.cpp
+++ b/safecode/runtime/KernelSafePoolAllocator/PageManager.cpp
@@ -63,15 +63,9 @@
// MAP_SHARED|MAP_ANONYMOUS, fdq, 0);
// void *pa = malloc(NumPages * PageSize);
// assert(Addr != MAP_FAILED && "MMAP FAILED!");
-#if POSIX_MEMALIGN
if (posix_memalign(&Addr, PageSize, NumPages*PageSize) != 0){
- assert(0 && "memalign failed \n");
+ assert(1 && "memalign failed \n");
}
-#else
- if ((Addr = valloc (NumPages*PageSize)) == 0){
- assert(0 && "valloc failed \n");
- }
-#endif
DEBUG(printf("memalign returns %x for %d\n", Addr, NumPages);)
// fprintf(fd1, "memory usage statistic :%d %d\n", getpid(), poolmemusage);
// fflush(fd1);
diff --git a/safecode/runtime/KernelSafePoolAllocator/PoolCheck.cpp b/safecode/runtime/KernelSafePoolAllocator/PoolCheck.cpp
index 1a37dfe..60fe708 100755
--- a/safecode/runtime/KernelSafePoolAllocator/PoolCheck.cpp
+++ b/safecode/runtime/KernelSafePoolAllocator/PoolCheck.cpp
@@ -79,22 +79,24 @@
return false;
}
-inline int refcheck(Splay *splay, void *Node) {
+
+inline bool refcheck(Splay *splay, void *Node) {
unsigned long base = (unsigned long) (splay->key);
unsigned long length = (unsigned long) (splay->val);
unsigned long result = (unsigned long) Node;
- if ((result >= base) && (result < (base + length))) return 1;
- return -1;
+ if ((result >= base) && (result < (base + length))) return true;
+ return false;
}
-int poolcheckarrayoptim(void *Pool, void *NodeSrc, void *NodeResult) {
+
+bool poolcheckarrayoptim(void *Pool, void *NodeSrc, void *NodeResult) {
Splay *psplay = poolchecksplay(Pool);
splay *ref = splay_find_ptr(psplay, (unsigned long)NodeSrc);
if (ref) {
return refcheck(ref, NodeResult);
}
- return 0;
+ return false;
}
void poolcheckarray(MetaPoolTy **MP, void *NodeSrc, void *NodeResult) {
@@ -112,41 +114,6 @@
poolcheckfail ("poolcheck failure \n");
}
-inline signed char * getactualvalue(signed char *Pool, signed char *val) {
- if ((unsigned long) val != 0x00000001) {
- return val;
- } else {
- poolcheckfail("Bounds check failure : value in the first page \n");
- }
-}
-
-inline void exactcheck2(signed char *base, signed char *result, unsigned size) {
- if (result >= base + size ) {
- poolcheckfail("Array bounds violation detected \n");
- }
-}
-
-
-
-void* boundscheck(MetaPoolTy **MP, void *NodeSrc, void *NodeResult) {
- MetaPoolTy *MetaPool = *MP;
- if (!MetaPool) {
- poolcheckfail ("Empty meta pool? \n");
- }
- //iteratively search through the list
- //Check if there are other efficient data structures.
- while (MetaPool) {
- void *Pool = MetaPool->Pool;
- int ret = poolcheckarrayoptim(Pool, NodeSrc, NodeResult);
- if (ret) {
- if (ret == -1) return ((void *)(0x00000001));
- return NodeResult;
- }
- MetaPool = MetaPool->next;
- }
- poolcheckfail ("poolcheck failure \n");
-}
-
void poolcheck(MetaPoolTy **MP, void *Node) {
MetaPoolTy *MetaPool = *MP;
if (!MetaPool) {
diff --git a/safecode/runtime/Makefile b/safecode/runtime/Makefile
index f289822..73aa89b 100755
--- a/safecode/runtime/Makefile
+++ b/safecode/runtime/Makefile
@@ -6,7 +6,7 @@
#
# List all of the subdirectories that we will compile.
#
-PARALLEL_DIRS=SafePoolAllocator BoundsCheckAllocator KernelSafePoolAllocator PoolCheck KPoolCheck
+PARALLEL_DIRS=SafePoolAllocator BoundsCheckAllocator KernelSafePoolAllocator
include $(LEVEL)/Makefile.common
diff --git a/safecode/runtime/PoolCheck/Makefile b/safecode/runtime/PoolCheck/Makefile
deleted file mode 100755
index 965458c..0000000
--- a/safecode/runtime/PoolCheck/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-LEVEL = ../..
-BYTECODE_LIBRARY=1
-LIBRARYNAME=poolcheck_rt
-
-include $(LEVEL)/Makefile.common
-
-# Always build optimized and debug versions
-all:: $(LIBNAME_OBJO) $(LIBNAME_OBJG)
diff --git a/safecode/runtime/PoolCheck/PoolCheck.c b/safecode/runtime/PoolCheck/PoolCheck.c
deleted file mode 100755
index 0ceae6d..0000000
--- a/safecode/runtime/PoolCheck/PoolCheck.c
+++ /dev/null
@@ -1,546 +0,0 @@
-/*===- PoolCheck.cpp - Implementation of poolcheck runtime ----------------===*/
-/* */
-/* The LLVM Compiler Infrastructure */
-/* */
-/* This file was developed by the LLVM research group and is distributed */
-/* under the University of Illinois Open Source License. See LICENSE.TXT for */
-/* details. */
-/* */
-/*===----------------------------------------------------------------------===*/
-/* */
-/* This file is one possible implementation of the LLVM pool allocator */
-/* runtime library. */
-/* */
-/*===----------------------------------------------------------------------===*/
-
-#include "PoolCheck.h"
-#ifdef LLVA_KERNEL
-#include <stdarg.h>
-#endif
-#define DEBUG(x)
-
-/* This defines the value of an invalid pointer address */
-static const unsigned char * invalidptr = 0x00000004;
-volatile unsigned char dosplays = 1;
-
-#if 1
-/*
- * These are symbols exported by the kernel so that we can figure out where
- * various sections are.
- */
-extern char _etext;
-extern char _edata;
-extern char __bss_start;
-extern char _end;
-#endif
-
-/*===----------------------------------------------------------------------===*/
-extern unsigned PageSize;
-
-/* Flag whether we are ready to perform pool operations */
-static int ready = 0;
-
-/*
- * Function: poolcheckinit()
- *
- * Description:
- * Initialization function to be called when the memory allocator run-time
- * intializes itself.
- *
- * Preconditions:
- * 1) The OS kernel is able to handle callbacks from the Execution Engine.
- */
-void
-poolcheckinit(void *Pool, unsigned NodeSize) {
- /*
- * Register all of the global variables in their respective meta pools.
- */
- poolcheckglobals();
-
- /*
- * Flag that we're ready to rumble!
- */
- ready = 1;
- return;
-}
-
-/*
- * Function: poolcheckdestroy()
- *
- * Description:
- * To be called from pooldestroy.
- */
-void
-poolcheckdestroy(void *Pool) {
- /* Do nothing as of now since all MetaPools are global */
-#if 0
- free_splay(Pool->splay);
-#endif
- ready = 0;
- return;
-}
-
-
-void AddPoolDescToMetaPool(MetaPoolTy **MP, void *P) {
- MetaPoolTy *MetaPoolPrev = *MP;
- MetaPoolTy *MetaPool = *MP;
- if (!ready) return;
- if (MetaPool) {
- MetaPool = MetaPool->next;
- } else {
- if (*MP = (MetaPoolTy *) poolcheckmalloc (sizeof(MetaPoolTy)))
- {
- (*MP)->Pool = P;
- (*MP)->Splay = 0;
- (*MP)->next = 0;
- }
- return;
- }
-
- /*
- * Scan for the end of the list. If we run across the pool already in the
- * meta-pool list, then don't bother adding it again.
- */
- while (MetaPool) {
- if (MetaPool->Pool == P) {
- return;
- }
- MetaPoolPrev = MetaPool;
- MetaPool = MetaPool->next;
- }
- /* MetaPool is null; */
- if (MetaPoolPrev->next = (MetaPoolTy *) poolcheckmalloc (sizeof(MetaPoolTy)))
- {
- MetaPoolPrev->next->Pool = P;
- MetaPoolPrev->next->Splay = 0;
- MetaPoolPrev->next->next = 0;
- }
-}
-
-
-/*
- * Function: poolcheckoptim()
- *
- * Description:
- * Determine whether the pointer is within the pool.
- *
- * Return value:
- * 1 - The pointer is within the pool.
- * 0 - The pointer is not within the pool.
- */
-unsigned char poolcheckoptim(void *Pool, void *Node) {
- Splay *psplay;
- Splay *ref;
-#if 0
- /*
- * Determine if this is a global variable in the data section.
- */
- if (((Node) >= &_etext) && ((Node) <= &_edata))
- {
- return;
- }
-
- /*
- * Determine if this is a global variable in the BSS section.
- */
- if ((((Node)) >= &__bss_start) && (((Node)) <= &_end))
- {
- return;
- }
-#endif
-
- /*
- * Determine the size of the slabs used in this pool.
- * Then, assuming this is the pool in which this node lives, determine
- * the slab to which the node would belong.
- */
- unsigned int SlabSize = poolcheckslabsize (Pool);
- void *PS = (void *)((unsigned)Node & ~(SlabSize-1));
-
- /*
- * Scan through the list of slabs belonging to the pool and determine
- * whether this node is in one of those slabs.
- */
- PoolCheckSlab * PCS = poolcheckslab(Pool);
- while (PCS) {
- if (PCS->Slab == PS) return 1;
- /* we can optimize by moving it to the front of the list */
- PCS = PCS->nextSlab;
- }
-
- /*
- * Here we check for the splay tree
- */
- psplay = poolchecksplay(Pool);
- ref = splay_find_ptr(psplay, (unsigned long) Node);
- if (ref) {
- return 1;
- }
- return 0;
-}
-
-/*
- * Function: poolcheckarrayoptim()
- *
- * Description:
- * This function determines:
- * 1) Whether the source node of a GEP is in the correct pool, and
- * 2) Whether the result of the GEP expression is in the same pool as the
- * source.
- *
- * Return value:
- * 1 - The source and destination were found in the pool.
- * 0 - The source was not found in the pool
- * -1 - The source was found in the pool, but the result is outside of the pool.
- */
-char
-poolcheckarrayoptim(MetaPoolTy *Pool, void *NodeSrc, void *NodeResult) {
- Splay *psplay = poolchecksplay(Pool);
- Splay *ref = splay_find_ptr(psplay, (unsigned long)NodeSrc);
- if (ref) {
- return refcheck(ref, NodeResult);
- }
- return 0;
-}
-
-/*
- * Function: poolcheckarray()
- *
- * Description:
- * This function performs the same check as poolcheckarrayoptim(), but
- * checks all the pools associated with a meta-pool.
- */
-void poolcheckarray(MetaPoolTy **MP, void *NodeSrc, void *NodeResult) {
- if (!ready) return;
- MetaPoolTy *MetaPool = *MP;
- if (!MetaPool) {
- poolcheckfail ("Empty meta pool? Src \n", NodeSrc);
- }
- /*
- * iteratively search through the list
- * Check if there are other efficient data structures.
- */
- while (MetaPool) {
- void *Pool = MetaPool->Pool;
- if ((Pool) && (poolcheckarrayoptim(Pool, NodeSrc, NodeResult))) return ;
- MetaPool = MetaPool->next;
- }
- poolcheckfail ("poolcheckarray failure: Result \n", NodeResult);
-}
-
-/*
- * Function: poolcheckiarray ()
- *
- * Description:
- * This function performs the same check as poolcheckarray() but
- * allows the check to succeed if the source node is not found.
- */
-void poolcheckiarray(MetaPoolTy **MP, void *NodeSrc, void *NodeResult) {
- if (!ready) return;
- MetaPoolTy *MetaPool = *MP;
- if (!MetaPool) {
- poolcheckfail ("Empty meta pool? Src \n", NodeSrc);
- }
-
- /*
- * iteratively search through the list
- * Check if there are other efficient data structures.
- */
- while (MetaPool) {
- void *Pool = MetaPool->Pool;
- if (Pool)
- if (poolcheckoptim (Pool, NodeSrc))
- if (poolcheckoptim (Pool, NodeResult))
- return;
- else
- poolcheckfail ("poolcheckiarray failure: Result \n", NodeResult);
- MetaPool = MetaPool->next;
- }
-
- return;
-}
-
-inline int refcheck(Splay *splay, void *Node) {
- unsigned long base = (unsigned long) (splay->key);
- unsigned long length = (unsigned long) (splay->val);
- unsigned long result = (unsigned long) Node;
- if ((result >= base) && (result < (base + length))) return 1;
- return -1;
-
-}
-
-inline signed char * getactualvalue(signed char *Pool, signed char *val) {
- if (!ready) return val;
- if ((unsigned long) val != invalidptr) {
- return val;
- } else {
- poolcheckfail("Bounds check failure : value in the first page \n", val);
- }
-}
-
-inline void exactcheck2(signed char *base, signed char *result, unsigned size) {
- if (result >= base + size ) {
- poolcheckfail("Array bounds violation detected \n", base);
- }
-}
-
-/*
- * Function: boundscheck()
- *
- * Description:
- * Perform a precise array bounds check on source and result. If the result
- * is out of range for the array, return 0x1 so that getactualvalue() will
- * know that the pointer is bad and should not be dereferenced.
- */
-void *
-boundscheck(MetaPoolTy **MP, void *NodeSrc, void *NodeResult) {
- MetaPoolTy *MetaPool = *MP;
- Splay *ref;
- void *Pool;
- int ret;
-
- if (!ready) return NodeResult;
-#if 0
- if (!MetaPool) {
- poolcheckfail ("Empty meta pool? \n", __builtin_return_address(0));
- }
-#endif
-
- /*
- * Iteratively search through the list;
- * Check if there are other efficient data structures.
- */
- while (MetaPool) {
- Pool = MetaPool->Pool;
- if (Pool) {
- ret = poolcheckarrayoptim(Pool, NodeSrc, NodeResult);
- if (ret) {
- if (ret == -1) return invalidptr;
- return NodeResult;
- }
- }
-
- if ((MetaPool->Splay)) {
- ref = splay_find_ptr (MetaPool->Splay, (unsigned long) NodeSrc);
- if (ref)
- if ((refcheck (ref, NodeResult)) == 1)
- return NodeResult;
- else {
- poolcheckfail ("boundscheck: global", NodeResult);
- return NodeResult;
- }
- }
-
- MetaPool = MetaPool->next;
- }
-
- /*
- * The node is not found or is not within bounds; fail!
- */
- poolcheckfail ("boundscheck failure 1\n", NodeSrc);
- return NodeResult;
-}
-
-/*
- * Function: uiboundscheck()
- *
- * Description:
- * Perform a precise array bounds check on source and result. If the result
- * is out of range for the array, return a sentinel so that getactualvalue()
- * will know that the pointer is bad and should not be dereferenced.
- *
- * This version differs from boundscheck() in that it does not generate a
- * poolcheck failure if the source node cannot be found within the MetaPool.
- */
-void *
-uiboundscheck (MetaPoolTy **MP, void *NodeSrc, void *NodeResult) {
- MetaPoolTy *MetaPool = *MP;
- Splay *ref;
- void *Pool;
- int ret;
-
- return NodeResult;
- /* Don't do a check if the kernel is not ready */
- if (!ready) return NodeResult;
-
- /* It is an error if there is no MetaPool */
- if (!MetaPool) {
- poolcheckfail ("Empty meta pool? \n", 0);
- }
-
- /*
- * iteratively search through the list
- * Check if there are other efficient data structures.
- */
- while (MetaPool) {
- Pool = MetaPool->Pool;
- if (Pool) {
- ret = poolcheckarrayoptim(Pool, NodeSrc, NodeResult);
- switch (ret) {
- case -1:
- return invalidptr;
- break;
- case 1:
- return NodeResult;
- break;
- case 0:
- break;
- }
- }
-
- /*
- * Search the Meta Pool's splay; the pointer might be a global or stack
- * value.
- */
- if ((dosplays) && (MetaPool->Splay)) {
- ref = splay_find_ptr (MetaPool->Splay, (unsigned long) NodeSrc);
- if (ref)
- if ((refcheck (ref, NodeResult)) == 1)
- return NodeResult;
- else
- return invalidptr;
- }
-
- MetaPool = MetaPool->next;
- }
-
- /*
- * We did not find the source node at all. For incomplete and unknown
- * pointers, this means we just silently pass.
- */
- return NodeResult;
-}
-
-
-
-/*
- * Function: poolcheck()
- *
- * Description:
- * Verify whether a node is located within one of the pools associated with
- * the MetaPool.
- */
-void poolcheck(MetaPoolTy **MP, void *Node) {
- if (!ready) return;
- MetaPoolTy *MetaPool = *MP;
- if (!MetaPool) {
- poolcheckfail ("Empty meta pool? \n", Node);
- }
- /*
- * iteratively search through the list
- * Check if there are other efficient data structures.
- */
- while (MetaPool) {
- void *Pool = MetaPool->Pool;
- if ((Pool) && (poolcheckoptim(Pool, Node))) return;
- MetaPool = MetaPool->next;
- }
- poolcheckfail ("poolcheck failure \n", Node);
-}
-
-
-void poolcheckAddSlab(PoolCheckSlab **PCSPtr, void *Slab) {
- PoolCheckSlab *PCSPrev = *PCSPtr;
- PoolCheckSlab *PCS = *PCSPtr;
- if (!ready) return;
- if (PCS) {
- PCS = PCS->nextSlab;
- } else {
- if (*PCSPtr = (PoolCheckSlab *) poolcheckmalloc (sizeof(PoolCheckSlab)))
- {
- (*PCSPtr)->Slab = Slab;
- (*PCSPtr)->nextSlab = 0;
- }
- return;
- }
- while (PCS) {
- PCSPrev = PCS;
- PCS = PCS->nextSlab;
- }
- /* PCS is null; */
- if (PCSPrev->nextSlab = (PoolCheckSlab *) poolcheckmalloc (sizeof(PoolCheckSlab)))
- {
- PCSPrev->nextSlab->Slab = Slab;
- PCSPrev->nextSlab->nextSlab = 0;
- }
-}
-
-
- void exactcheck(int a, int b) {
- if ((0 > a) || (a >= b)) {
- poolcheckfail ("exact check failed\n", (a));
- poolcheckfail ("exact check failed\n", (b));
- }
- }
-
- /*
- * Disable this for kernel code. I'm not sure how kernel code handles
- * va_list type functions.
- */
-#ifdef LLVA_KERNEL
- void funccheck(unsigned num, void *f, void *g, ...) {
- va_list ap;
- unsigned i = 0;
- if (f == g) return;
- i++;
- va_start(ap, g);
- for ( ; i != num; ++i) {
- void *h = va_arg(ap, void *);
- if (f == h) {
- return;
- }
- }
- abort();
- }
-#endif
-
-/*
- * Function: poolregister()
- *
- * Description:
- * Associate a memory range with a given MetaPool.
- *
- * Preconditions:
- * For now, we assume that this function is only called by poolcheckglobals()
- * which is called by poolcheckinit().
- */
-void
-poolregister (MetaPoolTy ** MP, unsigned NumBytes, void * ptr)
-{
- MetaPoolTy *MetaPool = *MP;
-
- /*
- * Allocate a MetaPool node if one does not already exist.
- */
- if (!MetaPool) {
- if (MetaPool = *MP = (MetaPoolTy *) poolcheckmalloc (sizeof(MetaPoolTy))) {
- (*MP)->Pool = 0;
- (*MP)->Splay = 0;
- (*MP)->next = 0;
- } else {
- poolcheckfatal ("poolregister: Cannot allocate memory", 0);
- }
- }
-
- /* Allocate a new splay for this node if needed */
- if (!(MetaPool->Splay))
- if (!(MetaPool->Splay = new_splay()))
- poolcheckfatal ("poolregister: Cannot allocate splay\n", 0);
-
- /*
- * Register the memory range with the MetaPool's splay.
- */
- splay_insert_ptr(MetaPool->Splay, (unsigned long)(ptr), NumBytes);
-}
-
-/*
- * Function: poolcheckregister()
- *
- * Description:
- * This function registers a range of memory as belonging to the splay. It is
- * currently used to register arrays, stack nodes, and global nodes.
- */
-void poolcheckregister(Splay *splay, void * allocaptr, unsigned NumBytes) {
- if (!ready) return;
- splay_insert_ptr(splay, (unsigned long)(allocaptr), NumBytes);
-}
diff --git a/safecode/runtime/PoolCheck/PoolCheck.h b/safecode/runtime/PoolCheck/PoolCheck.h
deleted file mode 100755
index f48e02a..0000000
--- a/safecode/runtime/PoolCheck/PoolCheck.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*===- PoolCheck.h - Pool check runtime interface file --------------------===*/
-/* */
-/* The LLVM Compiler Infrastructure */
-/* */
-/* This file was developed by the LLVM research group and is distributed */
-/* under the University of Illinois Open Source License. See LICENSE.TXT for */
-/* details. */
-/* */
-/*===----------------------------------------------------------------------===*/
-/* */
-/* */
-/*===----------------------------------------------------------------------===*/
-
-#ifndef POOLCHECK_RUNTIME_H
-#define POOLCHECK_RUNTIME_H
-
-#include "PoolSystem.h"
-#include "splay.h"
-
-typedef struct PoolCheckSlab {
- void *Slab;
- struct PoolCheckSlab *nextSlab;
-} PoolCheckSlab;
-
-typedef struct MetaPoolTy {
- // Pointer to the OS pool that this MetaPool node describes
- void * Pool;
-
- // A splay for registering stack and global values
- Splay * Splay;
-
- // A pointer to the next pool in the list
- struct MetaPoolTy *next;
-} MetaPoolTy;
-
-
-#ifdef __cpluscplus
-extern "C" {
-#endif
- /* register that starting from allocaptr numbytes are a part of the pool */
- void poolcheck(MetaPoolTy **Pool, void *Node);
- unsigned char poolcheckoptim(void *Pool, void *Node);
- void poolcheckregister(Splay *splay, void * allocaptr, unsigned NumBytes);
- void AddPoolDescToMetaPool(MetaPoolTy **MetaPool, void *PoolDesc);
- void poolcheckarray(MetaPoolTy **Pool, void *Node, void * Node1);
- void poolcheckiarray(MetaPoolTy **Pool, void *Node, void * Node1);
- char poolcheckarrayoptim(MetaPoolTy *Pool, void *Node, void * Node1);
- void poolcheckAddSlab(PoolCheckSlab **PoolCheckSlabPtr, void *Slab);
- void poolcheckinit(void *Pool, unsigned NodeSize);
- void poolcheckdestroy(void *Pool);
- void poolcheckfree(void *Pool, void *Node);
-
- /* Functions that need to be provided by the pool allocation run-time */
- PoolCheckSlab *poolcheckslab(void *Pool);
- Splay *poolchecksplay(void *Pool);
- unsigned poolcheckslabsize (void * Pool);
-#ifdef __cpluscplus
-}
-#endif
-
-#endif
diff --git a/safecode/runtime/PoolCheck/PoolSystem.h b/safecode/runtime/PoolCheck/PoolSystem.h
deleted file mode 100755
index 42289ff..0000000
--- a/safecode/runtime/PoolCheck/PoolSystem.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*===- PoolSystem.h - Pool check runtime interface to the system ----------===*/
-/* */
-/* The LLVM Compiler Infrastructure */
-/* */
-/* This file was developed by the LLVM research group and is distributed */
-/* under the University of Illinois Open Source License. See LICENSE.TXT for */
-/* details. */
-/* */
-/*===----------------------------------------------------------------------===*/
-/* */
-/* */
-/*===----------------------------------------------------------------------===*/
-
-#ifndef POOLSYSTEM_RUNTIME_H
-#define POOLSYSTEM_RUNTIME_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
- /* Functions that need to be provided by the pool allocation run-time */
- void poolcheckfail (const char * msg, int);
- void poolcheckfatal (const char * msg, int);
- void poolcheckinfo (const char * msg, int);
- void * poolcheckmalloc (unsigned int size);
- void printpoolinfo (void *Pool);
- void poolcheckglobals ();
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/safecode/runtime/PoolCheck/splay.c b/safecode/runtime/PoolCheck/splay.c
deleted file mode 100755
index 9c1d96f..0000000
--- a/safecode/runtime/PoolCheck/splay.c
+++ /dev/null
@@ -1,326 +0,0 @@
-/*
- * Note: This file is obtained from
- * http://www.cs.utk.edu/~cs140/spring-2005/notes/Splay/
- * FIXME: This may not be the most efficient version of splay implementation
- * This may be updated with a different splay implementation in near future
- */
-
-#include "PoolSystem.h"
-#include <stdio.h>
-#include "splay.h"
-#include <stdlib.h>
-void rotate(Splay *node)
-{
- Splay *parent, *grandparent;
-
- if (node->parent->is_sentinel) return;
-
- parent = node->parent;
- grandparent = parent->parent;
-
- if (parent->left == node) {
- parent->left = node->right;
- if (parent->left != NULL) parent->left->parent = parent;
- node->right = parent;
- } else if (parent->right == node) {
- parent->right = node->left;
- if (parent->right != NULL) parent->right->parent = parent;
- node->left = parent;
- } else {
- fprintf(stderr, "rotate: error: parent's children are not right\n");
- exit(1);
- }
-
- parent->parent = node;
- node->parent = grandparent;
-
- if (grandparent->is_sentinel) {
- grandparent->parent = node;
- } else if (grandparent->left == parent) {
- grandparent->left = node;
- } else if (grandparent->right == parent) {
- grandparent->right = node;
- } else {
- fprintf(stderr, "rotate: error: grandparent's children are not right\n");
- exit(1);
- }
-}
-
- void splay(Splay *node)
-{
- Splay *parent, *grandparent;
-
- if (node->is_sentinel) return;
-
- while(1) {
- if (node->parent->is_sentinel) return;
-
- parent = node->parent;
- grandparent = parent->parent;
-
- /* If the node's parent is the root of the tree, do one rotation */
-
- if (grandparent->is_sentinel) {
- rotate(node);
-
- /* If we have a zig-zig, then rotate my parent, then rotate me */
-
- } else if ((parent->left == node && grandparent->left == parent) ||
- (parent->right == node && grandparent->right == parent)) {
- rotate(parent);
- rotate(node);
-
- /* If we have a zig-zag, then rotate me twice */
-
- } else {
- rotate(node);
- rotate(node);
- }
- }
-}
-
-Splay *new_splay()
-{
- Splay *tree;
-
- tree = (Splay *) poolcheckmalloc (sizeof(struct splay));
- tree->key = 0;
- tree->val = 0;
- tree->is_sentinel = 1;
- tree->flink = tree;
- tree->blink = tree;
- tree->left = NULL;
- tree->right = NULL;
- tree->parent = NULL;
- return tree;
-}
-
-Splay *splay_root(Splay *tree)
-{
- return tree->parent;
-}
-
-Splay *splay_first(Splay *tree)
-{
- return tree->flink;
-}
-
-Splay *splay_last(Splay *tree)
-{
- return tree->blink;
-}
-
-Splay *splay_next(Splay *node)
-{
- return node->flink;
-}
-
-Splay *splay_prev(Splay *node)
-{
- return node->blink;
-}
-
-Splay *splay_nil(Splay *tree)
-{
- return tree;
-}
-
-void free_splay(Splay *tree)
-{
- Splay *ptr;
-
- while (1) {
- ptr = splay_first(tree);
- if (!ptr->is_sentinel) {
- splay_delete_node(ptr);
- } else {
- free(ptr);
- return;
- }
- }
-}
-
- Splay *splay_find_nearest_ptr(Splay *tree, unsigned long key, int *cmpval)
-{
- Splay *s, *last;
- int cmp;
-
- last = tree;
- s = splay_root(tree);
- cmp = 1;
-
- while(s != NULL) {
- last = s;
- if (key == s->key) {
- *cmpval = 0;
- return s;
- } else if (key < (s->key)) {
- s = s->left;
- cmp = -1;
- } else {
- if (key < (s->val + s->key)) {
- *cmpval = 0;
- return s;
- }
- s = s->right;
- cmp = 1;
- }
- }
-
- *cmpval = cmp;
- return last;
-}
-
-
-Splay *splay_find_ptr(Splay *tree, unsigned long key)
-{
- int cmpval;
- Splay *s;
-
- s = splay_find_nearest_ptr(tree, key, &cmpval);
- splay(s);
- if (cmpval == 0) return s; else return NULL;
-}
-
-
-Splay *splay_insert(Splay *tree, Jval key, Jval val, Splay *parent, int cmpval)
-{
- Splay *s;
-
- s = (Splay *) poolcheckmalloc (sizeof(struct splay));
- s->is_sentinel = 0;
- s->parent = parent;
- s->left = NULL;
- s->right = NULL;
- s->key = key;
- s->val = val;
-
- /* Set the parent's correct child pointer. The only
- subtle case here is when the key is already in
- the tree -- then we need to find a leaf node
- to use as a parent */
-
- /* When we're done here, parent should point to the
- new node's successor in the linked list */
-
- if (parent->is_sentinel) {
- parent->parent = s;
- } else {
- if (cmpval == 0) { /* If the key is already in the
- tree, try to insert a new one as the
- node's right child. If the node already
- has a right child, then try to insert the
- new one as a left child. If there is already
- a left child, then go to parent-flink and
- insert the node as its left child. */
- if (parent->right == NULL) {
- cmpval = 1;
- } else if (parent->left == NULL) {
- cmpval = -1;
- } else {
- parent = parent->flink;
- s->parent = parent;
- cmpval = -1;
- }
- }
- if (cmpval > 0) { /* Insert as right child */
- if (parent->right != NULL) {
- fprintf(stderr, "splay_insert error: parent->right != NULL");
- exit(1);
- }
- parent->right = s;
- parent = parent->flink;
- } else {
- if (parent->left != NULL) {
- fprintf(stderr, "splay_insert error: parent->left != NULL");
- exit(1);
- }
- parent->left = s;
- }
- }
-
- s->flink = parent;
- s->blink = parent->blink;
- s->flink->blink = s;
- s->blink->flink = s;
- splay(s);
- return s;
-}
-
-Splay *splay_insert_ptr(Splay *tree, unsigned long key, Jval val)
-{
- Splay *parent;
- int cmpval;
-
- parent = splay_find_nearest_ptr(tree, key, &cmpval);
- return splay_insert(tree, key, val, parent, cmpval);
-}
-
-extern void splay_delete_node(Splay *node)
-{
- Splay *left, *right, *tree, *newroot;
-
- splay(node);
-
- tree = node->parent;
-
- left = node->left;
- right = node->right;
- newroot = node->flink;
-
- node->flink->blink = node->blink;
- node->blink->flink = node->flink;
-
- free(node);
-
- if (right == NULL && left == NULL) {
- tree->parent = NULL;
- } else if (right == NULL) {
- tree->parent = left;
- left->parent = tree;
- } else if (left == NULL) {
- tree->parent = right;
- right->parent = tree;
- } else {
- tree->parent = right;
- right->parent = tree;
- splay(newroot);
- newroot->left = left;
- left->parent = newroot;
- }
-}
- Splay *finish_gte(int cmpval, Splay *s, int *found)
-{
-
- if (cmpval == 0) {
- *found = 1;
- return s;
- } else if (cmpval < 0) {
- *found = 0;
- return s;
- } else {
- *found = 1;
- return s->flink;
- }
-}
-/*
-Splay *splay_find_gte_str(Splay *tree, char *key, int *found)
-{
- int cmpval;
- Splay *s;
-
- s = splay_find_nearest_str(tree, key, &cmpval);
- return finish_gte(cmpval, s, found);
-}
-*/
-
-Splay *splay_find_gte_ptr(Splay *tree, unsigned long key, int *found)
-{
- int cmpval;
- Splay *s;
-
- s = splay_find_nearest_ptr(tree, key, &cmpval);
- return finish_gte(cmpval, s, found);
-}
-
-
diff --git a/safecode/runtime/PoolCheck/splay.h b/safecode/runtime/PoolCheck/splay.h
deleted file mode 100755
index 68c2e76..0000000
--- a/safecode/runtime/PoolCheck/splay.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Note: This file is obtained from
- * http://www.cs.utk.edu/~cs140/spring-2005/notes/Splay/
- * FIXME: This may not be the most efficient version of splay implementation
- * This may be updated with a different splay implementation in near future
- */
-
-#ifndef _SPLAY_
-#define _SPLAY_
-
-typedef unsigned long Jval ;
-
-/* Node identities */
-
-#define SPLAY_SENTINEL 0
-#define SPLAY_OTHER 1
-
-typedef struct splay {
- Jval key;
- Jval val;
- int is_sentinel;
- struct splay *left;
- struct splay *right;
- struct splay *flink;
- struct splay *blink;
- struct splay *parent;
-} Splay;
-
-#ifdef __cplusplus
-extern "C" {
-#endif
- Splay *new_splay();
- void free_splay(Splay *);
- Splay *splay_insert_ptr(Splay *tree, unsigned long key, Jval val);
- Splay *splay_find_ptr(Splay *tree, unsigned long key);
- Splay *splay_find_gte_ptr(Splay *tree, unsigned long key, int *found);
-
- Splay *splay_root(Splay *tree);
- Splay *splay_first(Splay *tree);
- Splay *splay_last(Splay *tree);
- Splay *splay_next(Splay *node);
- Splay *splay_prev(Splay *node);
- Splay *splay_nil(Splay *tree);
-
- void splay_delete_node(Splay *node);
-#ifdef __cplusplus
-}
-#endif
-
-#define splay_traverse(ptr, list) \
- for (ptr = splay_first(list); ptr != splay_nil(list); ptr = splay_next(ptr))
-#define splay_rtraverse(ptr, list) \
- for (ptr = splay_last(list); ptr != splay_nil(list); ptr = splay_prev(ptr))
-
-#endif
diff --git a/safecode/runtime/SafePoolAllocator/PageManager.cpp b/safecode/runtime/SafePoolAllocator/PageManager.cpp
index a03cc8b..cdf549d 100755
--- a/safecode/runtime/SafePoolAllocator/PageManager.cpp
+++ b/safecode/runtime/SafePoolAllocator/PageManager.cpp
@@ -59,15 +59,9 @@
// MAP_SHARED|MAP_ANONYMOUS, fd, 0);
// void *pa = malloc(NumPages * PageSize);
// assert(Addr != MAP_FAILED && "MMAP FAILED!");
-#if POSIX_MEMALIGN
if (posix_memalign(&Addr, PageSize, NumPages*PageSize) != 0){
- assert(0 && "memalign failed \n");
+ assert(1 && "memalign failed \n");
}
-#else
- if ((Addr = valloc (NumPages*PageSize)) == 0){
- assert(0 && "valloc failed \n");
- }
-#endif
poolmemusage += NumPages * PageSize;
memset(Addr, 0xcc, NumPages *PageSize);
return Addr;
diff --git a/safecode/tools/Makefile b/safecode/tools/Makefile
index d99cd10..2244d19 100755
--- a/safecode/tools/Makefile
+++ b/safecode/tools/Makefile
@@ -1,5 +1,5 @@
LEVEL = ..
-PARALLEL_DIRS = Sc
+PARALLEL_DIRS =
include $(LEVEL)/Makefile.common