Add support for building with -fsanitize=undefined.
- add configure option --enable-ubsan
- add __ubsan helpers (by Julian)
This requires gcc 4.9.2 or later. Not all platforms are supported, though.
With this change and VEX r3099 regression tests pass on amd64
with a valgrind compiled with -fsanitize=undefined.
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@14995 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/Makefile.all.am b/Makefile.all.am
index 3b2772a..860ef90 100644
--- a/Makefile.all.am
+++ b/Makefile.all.am
@@ -111,6 +111,7 @@
@FLAG_W_FORMAT@ \
@FLAG_W_FORMAT_SECURITY@ \
@FLAG_FNO_STACK_PROTECTOR@ \
+ @FLAG_FSANITIZE@ \
-fno-strict-aliasing \
-fno-builtin
diff --git a/auxprogs/Makefile.am b/auxprogs/Makefile.am
index c3c67a4..89ca89b 100644
--- a/auxprogs/Makefile.am
+++ b/auxprogs/Makefile.am
@@ -72,7 +72,7 @@
getoff_@VGCONF_ARCH_PRI@_@VGCONF_OS@_CPPFLAGS = $(AM_CPPFLAGS_@VGCONF_PLATFORM_PRI_CAPS@)
getoff_@VGCONF_ARCH_PRI@_@VGCONF_OS@_CFLAGS = $(AM_CFLAGS_@VGCONF_PLATFORM_PRI_CAPS@)
getoff_@VGCONF_ARCH_PRI@_@VGCONF_OS@_CCASFLAGS = $(AM_CCASFLAGS_PRI)
-getoff_@VGCONF_ARCH_PRI@_@VGCONF_OS@_LDFLAGS = $(AM_CFLAGS_PRI)
+getoff_@VGCONF_ARCH_PRI@_@VGCONF_OS@_LDFLAGS = $(AM_CFLAGS_PRI) @LIB_UBSAN@
if HAVE_DLINFO_RTLD_DI_TLS_MODID
getoff_@VGCONF_ARCH_PRI@_@VGCONF_OS@_LDADD = $(LDADD) -ldl
endif
diff --git a/configure.ac b/configure.ac
index ebb0798..e731af9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -827,6 +827,16 @@
VALT_LOAD_ADDRESS_SEC=$valt_load_address_sec_norml
fi
+#----------------------------------------------------------------------------
+# Undefined behaviour sanitiser
+#----------------------------------------------------------------------------
+# Check whether we should build with the undefined beahviour sanitiser.
+
+AC_CACHE_CHECK([for using the undefined behaviour sanitiser], vg_cv_ubsan,
+ [AC_ARG_ENABLE(ubsan,
+ [ --enable-ubsan enables the undefined behaviour sanitiser],
+ [vg_cv_ubsan=$enableval],
+ [vg_cv_ubsan=no])])
#----------------------------------------------------------------------------
# Define MIPS_PAGE_SHIFT (--with-pagesize)
@@ -1777,6 +1787,28 @@
AC_SUBST(FLAG_FNO_STACK_PROTECTOR)
+
+# Does this compiler support -fsanitize=undefined?
+# Only checked for if --enable-ubsan was given.
+if test "x${vg_cv_ubsan}" = "xyes"; then
+AC_MSG_CHECKING([if gcc accepts -fsanitize=undefined])
+safe_CFLAGS=$CFLAGS
+CFLAGS="-fsanitize=undefined"
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[
+ return 0;
+]])], [
+FLAG_FSANITIZE="-fsanitize=undefined"
+LIB_UBSAN="-static-libubsan"
+AC_MSG_RESULT([yes])
+], [
+FLAG_FSANITIZE=""
+LIB_UBSAN=""
+AC_MSG_RESULT([no])
+])
+CFLAGS=$safe_CFLAGS
+AC_SUBST(FLAG_FSANITIZE)
+AC_SUBST(LIB_UBSAN)
+fi
# does this compiler support --param inline-unit-growth=... ?
AC_MSG_CHECKING([if gcc accepts --param inline-unit-growth])
diff --git a/coregrind/Makefile.am b/coregrind/Makefile.am
index 64e1459..d07be73 100644
--- a/coregrind/Makefile.am
+++ b/coregrind/Makefile.am
@@ -48,7 +48,7 @@
valgrind_CPPFLAGS = $(AM_CPPFLAGS_PRI)
valgrind_CFLAGS = $(AM_CFLAGS_PRI)
valgrind_CCASFLAGS = $(AM_CCASFLAGS_PRI)
-valgrind_LDFLAGS = $(AM_CFLAGS_PRI)
+valgrind_LDFLAGS = $(AM_CFLAGS_PRI) @LIB_UBSAN@
if VGCONF_PLATFORMS_INCLUDE_X86_DARWIN
valgrind_LDFLAGS += -Wl,-read_only_relocs -Wl,suppress
endif
@@ -77,7 +77,7 @@
vgdb_CPPFLAGS = $(AM_CPPFLAGS_PRI)
vgdb_CFLAGS = $(AM_CFLAGS_PRI)
vgdb_CCASFLAGS = $(AM_CCASFLAGS_PRI)
-vgdb_LDFLAGS = $(AM_CFLAGS_PRI)
+vgdb_LDFLAGS = $(AM_CFLAGS_PRI) @LIB_UBSAN@
if VGCONF_PLATVARIANT_IS_ANDROID
vgdb_CFLAGS += -static
endif
diff --git a/coregrind/m_compiler.c b/coregrind/m_compiler.c
index 21c7c7a..f39a90f 100644
--- a/coregrind/m_compiler.c
+++ b/coregrind/m_compiler.c
@@ -39,6 +39,8 @@
#include "config.h"
#include "pub_core_basics.h"
#include "pub_core_libcbase.h"
+#include "pub_core_libcassert.h"
+#include "pub_core_debuglog.h"
#ifndef HAVE_BUILTIN_POPCOUT
@@ -218,6 +220,81 @@
#endif
+
+/*====================================================================*/
+/*=== gcc -fsanitize=undefined helper function support ===*/
+/*====================================================================*/
+
+void __ubsan_handle_type_mismatch ( void );
+void __ubsan_handle_type_mismatch ( void )
+{
+ VG_(debugLog)(0, "main:ubsan", "In %s", __func__);
+ vg_assert(0);
+}
+
+void __ubsan_handle_mul_overflow ( void );
+void __ubsan_handle_mul_overflow ( void )
+{
+ VG_(debugLog)(0, "main:ubsan", "In %s", __func__);
+ vg_assert(0);
+}
+
+void __ubsan_handle_add_overflow ( void );
+void __ubsan_handle_add_overflow ( void )
+{
+ VG_(debugLog)(0, "main:ubsan", "In %s", __func__);
+ vg_assert(0);
+}
+
+void __ubsan_handle_sub_overflow ( void );
+void __ubsan_handle_sub_overflow ( void )
+{
+ VG_(debugLog)(0, "main:ubsan", "In %s", __func__);
+ vg_assert(0);
+}
+
+void __ubsan_handle_divrem_overflow ( void );
+void __ubsan_handle_divrem_overflow ( void )
+{
+ VG_(debugLog)(0, "main:ubsan", "In %s", __func__);
+ vg_assert(0);
+}
+
+void __ubsan_handle_negate_overflow ( void );
+void __ubsan_handle_negate_overflow ( void )
+{
+ VG_(debugLog)(0, "main:ubsan", "In %s", __func__);
+ vg_assert(0);
+}
+
+void __ubsan_handle_out_of_bounds ( void );
+void __ubsan_handle_out_of_bounds ( void )
+{
+ VG_(debugLog)(0, "main:ubsan", "In %s", __func__);
+ vg_assert(0);
+}
+
+void __ubsan_handle_shift_out_of_bounds ( void );
+void __ubsan_handle_shift_out_of_bounds ( void )
+{
+ VG_(debugLog)(0, "main:ubsan", "In %s", __func__);
+ vg_assert(0);
+}
+
+void __ubsan_handle_vla_bound_not_positive ( void );
+void __ubsan_handle_vla_bound_not_positive ( void )
+{
+ VG_(debugLog)(0, "main:ubsan", "In %s", __func__);
+ vg_assert(0);
+}
+
+void __ubsan_handle_nonnull_arg ( void );
+void __ubsan_handle_nonnull_arg ( void )
+{
+ VG_(debugLog)(0, "main:ubsan", "In %s", __func__);
+ vg_assert(0);
+}
+
/*--------------------------------------------------------------------*/
/*--- end ---*/
/*--------------------------------------------------------------------*/
diff --git a/coregrind/m_libcbase.c b/coregrind/m_libcbase.c
index b9a7574..60cad36 100644
--- a/coregrind/m_libcbase.c
+++ b/coregrind/m_libcbase.c
@@ -694,28 +694,30 @@
void* VG_(memset) ( void *destV, Int c, SizeT sz )
{
- Int c4;
- HChar* d = (HChar*)destV;
+ UInt c4;
+ UChar* d = destV;
+ UChar uc = c;
+
while ((!VG_IS_4_ALIGNED(d)) && sz >= 1) {
- d[0] = c;
+ d[0] = uc;
d++;
sz--;
}
if (sz == 0)
return destV;
- c4 = c & 0xFF;
+ c4 = uc;
c4 |= (c4 << 8);
c4 |= (c4 << 16);
while (sz >= 16) {
- ((Int*)d)[0] = c4;
- ((Int*)d)[1] = c4;
- ((Int*)d)[2] = c4;
- ((Int*)d)[3] = c4;
+ ((UInt*)d)[0] = c4;
+ ((UInt*)d)[1] = c4;
+ ((UInt*)d)[2] = c4;
+ ((UInt*)d)[3] = c4;
d += 16;
sz -= 16;
}
while (sz >= 4) {
- ((Int*)d)[0] = c4;
+ ((UInt*)d)[0] = c4;
d += 4;
sz -= 4;
}
diff --git a/memcheck/tests/vbit-test/Makefile.am b/memcheck/tests/vbit-test/Makefile.am
index db6f6f5..9888fad 100644
--- a/memcheck/tests/vbit-test/Makefile.am
+++ b/memcheck/tests/vbit-test/Makefile.am
@@ -40,4 +40,4 @@
vbit_test_CFLAGS = $(AM_CFLAGS_PRI) -std=c99
vbit_test_DEPENDENCIES =
vbit_test_LDADD =
-vbit_test_LDFLAGS = $(AM_CFLAGS_PRI) -std=c99
+vbit_test_LDFLAGS = $(AM_CFLAGS_PRI) -std=c99 @LIB_UBSAN@