public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH 0/17] KASan 4.9 backport
@ 2014-10-16  8:35 Yury Gribov
  2014-10-16  8:36 ` [PATCH 1/17] Install asan_interface.h Yury Gribov
                   ` (17 more replies)
  0 siblings, 18 replies; 49+ messages in thread
From: Yury Gribov @ 2014-10-16  8:35 UTC (permalink / raw)
  To: GCC Patches
  Cc: Jakub Jelinek, Dmitry Vyukov, Konstantin Khlebnikov,
	Andrey Ryabinin, Viacheslav Garbuzov

Hi all,

As discussed in https://gcc.gnu.org/ml/gcc/2014-09/msg00234.html , this 
patchset backports mainline patches necessary for Kernel ASan in GCC 4.9 
(gcc-4_9-branch). The patcheset consists of
* Asan headers installation (1 patch)
* __asan_loadN/__asan_storeN support (3 patches)
* instrumentation with calls support (1 patch)
* optimization of strlen instrumentation (1 patch)
* Kasan support (3 patches)
* move inlining to sanopt (1 patches)
* bugfixes (7 patches)

To my knowledge it does not contain any changes that would influence ABI 
of generated code.

The code was bootstrapped and regtested on x64 (I only tested the net 
result, not each patch in isolation).

-Y

^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH 1/17] Install asan_interface.h
  2014-10-16  8:35 [PATCH 0/17] KASan 4.9 backport Yury Gribov
@ 2014-10-16  8:36 ` Yury Gribov
  2014-10-16  8:41   ` Jakub Jelinek
  2014-10-16  8:36 ` [PATCH 3/17] Instrumentation of unaligned types Yury Gribov
                   ` (16 subsequent siblings)
  17 siblings, 1 reply; 49+ messages in thread
From: Yury Gribov @ 2014-10-16  8:36 UTC (permalink / raw)
  To: GCC Patches
  Cc: Jakub Jelinek, Dmitry Vyukov, Konstantin Khlebnikov,
	Andrey Ryabinin, Viacheslav Garbuzov

[-- Attachment #1: Type: text/plain, Size: 356 bytes --]

This patch adds support for asan_interface.h installation (it's required 
by tests in other patches).

One change compared to mainline: asan_interface.h in 4.9 isn't C 
friendly (it uses bool type) so I had to replace bool with unsigned char 
in tests. The actual value isn't used by the test so I believe this 
shouldn't influence portability in any way.

[-- Attachment #2: 0001-2014-10-15-Yury-Gribov-y.gribov-samsung.com.patch --]
[-- Type: text/x-patch, Size: 9122 bytes --]

2014-10-15  Yury Gribov  <y.gribov@samsung.com>

	Backport from mainline
	2014-05-14  Yury Gribov  <y.gribov@samsung.com>

	PR sanitizer/61100

	* Makefile.am (nodist_saninclude_HEADERS): Install
	public headers.
	* Makefile.in: Regenerate.

	* c-c++-common/asan/asan-interface-1.c: New test.
	* lib/asan-dg.exp (asan_include_flags): New function.
	(asan_init): Call asan_include_flags to obtain path
	to sanitizer headers.

diff --git a/gcc/testsuite/c-c++-common/asan/asan-interface-1.c b/gcc/testsuite/c-c++-common/asan/asan-interface-1.c
new file mode 100644
index 0000000..55203ec
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/asan/asan-interface-1.c
@@ -0,0 +1,17 @@
+/* Check that interface headers work. */
+
+/* { dg-do run { target { *-*-linux* } } } */
+
+#ifndef __cplusplus
+#define bool unsigned char
+#endif
+
+#include <sanitizer/asan_interface.h>
+
+int main() {
+  char tmp;
+  if (__asan_address_is_poisoned((volatile char *)&tmp + 1))
+    return 0;
+  return 1;
+}
+
diff --git a/gcc/testsuite/lib/asan-dg.exp b/gcc/testsuite/lib/asan-dg.exp
index 9ba39db..7a12160 100644
--- a/gcc/testsuite/lib/asan-dg.exp
+++ b/gcc/testsuite/lib/asan-dg.exp
@@ -23,6 +23,21 @@ proc check_effective_target_faddress_sanitizer {} {
     } "-fsanitize=address"]
 }
 
+proc asan_include_flags {} {
+    global srcdir
+    global TESTING_IN_BUILD_TREE
+
+    set flags ""
+
+    if { [is_remote host] || ! [info exists TESTING_IN_BUILD_TREE] } {
+      return "${flags}"
+    }
+
+    set flags "-I$srcdir/../../libsanitizer/include"
+
+    return "$flags"
+}
+
 #
 # asan_link_flags -- compute library path and flags to find libasan.
 # (originally from g++.exp)
@@ -80,17 +95,19 @@ proc asan_init { args } {
 	}
     }
 
+    set include_flags "[asan_include_flags]"
+
     if [info exists TEST_ALWAYS_FLAGS] {
 	set asan_saved_TEST_ALWAYS_FLAGS $TEST_ALWAYS_FLAGS
     }
     if [info exists ALWAYS_CXXFLAGS] {
 	set ALWAYS_CXXFLAGS [concat "{ldflags=$link_flags}" $ALWAYS_CXXFLAGS]
-	set ALWAYS_CXXFLAGS [concat "{additional_flags=-fsanitize=address -g}" $ALWAYS_CXXFLAGS]
+	set ALWAYS_CXXFLAGS [concat "{additional_flags=-fsanitize=address -g $include_flags}" $ALWAYS_CXXFLAGS]
     } else {
 	if [info exists TEST_ALWAYS_FLAGS] {
-	    set TEST_ALWAYS_FLAGS "$link_flags -fsanitize=address -g $TEST_ALWAYS_FLAGS"
+	    set TEST_ALWAYS_FLAGS "$link_flags -fsanitize=address -g $include_flags $TEST_ALWAYS_FLAGS"
 	} else {
-	    set TEST_ALWAYS_FLAGS "$link_flags -fsanitize=address -g"
+	    set TEST_ALWAYS_FLAGS "$link_flags -fsanitize=address -g $include_flags"
 	}
     }
     if { $link_flags != "" } {
diff --git a/libsanitizer/Makefile.am b/libsanitizer/Makefile.am
index b0dc582..6b0c571 100644
--- a/libsanitizer/Makefile.am
+++ b/libsanitizer/Makefile.am
@@ -1,7 +1,13 @@
 ACLOCAL_AMFLAGS = -I .. -I ../config
 
+sanincludedir = $(libdir)/gcc/$(target_alias)/$(gcc_version)/include/sanitizer
+
+nodist_saninclude_HEADERS =
+
 if SANITIZER_SUPPORTED
 SUBDIRS = sanitizer_common
+nodist_saninclude_HEADERS += \
+  include/sanitizer/common_interface_defs.h
 if !USING_MAC_INTERPOSE
 SUBDIRS += interception
 endif
@@ -9,6 +15,9 @@ if LIBBACKTRACE_SUPPORTED
 SUBDIRS += libbacktrace
 endif
 SUBDIRS += lsan asan ubsan
+nodist_saninclude_HEADERS += \
+  include/sanitizer/lsan_interface.h \
+  include/sanitizer/asan_interface.h
 if TSAN_SUPPORTED
 SUBDIRS += tsan
 endif
diff --git a/libsanitizer/Makefile.in b/libsanitizer/Makefile.in
index 60cbe2e..0b89245 100644
--- a/libsanitizer/Makefile.in
+++ b/libsanitizer/Makefile.in
@@ -35,9 +35,12 @@ POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
 target_triplet = @target@
-@SANITIZER_SUPPORTED_TRUE@@USING_MAC_INTERPOSE_FALSE@am__append_1 = interception
-@LIBBACKTRACE_SUPPORTED_TRUE@@SANITIZER_SUPPORTED_TRUE@am__append_2 = libbacktrace
-@SANITIZER_SUPPORTED_TRUE@@TSAN_SUPPORTED_TRUE@am__append_3 = tsan
+@SANITIZER_SUPPORTED_TRUE@am__append_1 = include/sanitizer/common_interface_defs.h \
+@SANITIZER_SUPPORTED_TRUE@	include/sanitizer/lsan_interface.h \
+@SANITIZER_SUPPORTED_TRUE@	include/sanitizer/asan_interface.h
+@SANITIZER_SUPPORTED_TRUE@@USING_MAC_INTERPOSE_FALSE@am__append_2 = interception
+@LIBBACKTRACE_SUPPORTED_TRUE@@SANITIZER_SUPPORTED_TRUE@am__append_3 = libbacktrace
+@SANITIZER_SUPPORTED_TRUE@@TSAN_SUPPORTED_TRUE@am__append_4 = tsan
 subdir = .
 DIST_COMMON = ChangeLog $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
 	$(top_srcdir)/configure $(am__configure_deps) \
@@ -98,8 +101,9 @@ am__nobase_list = $(am__nobase_strip_setup); \
 am__base_list = \
   sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
   sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
-am__installdirs = "$(DESTDIR)$(toolexeclibdir)"
-HEADERS = $(nodist_toolexeclib_HEADERS)
+am__installdirs = "$(DESTDIR)$(sanincludedir)" \
+	"$(DESTDIR)$(toolexeclibdir)"
+HEADERS = $(nodist_saninclude_HEADERS) $(nodist_toolexeclib_HEADERS)
 RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive	\
   distclean-recursive maintainer-clean-recursive
 AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
@@ -250,9 +254,11 @@ top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 ACLOCAL_AMFLAGS = -I .. -I ../config
-@SANITIZER_SUPPORTED_TRUE@SUBDIRS = sanitizer_common $(am__append_1) \
-@SANITIZER_SUPPORTED_TRUE@	$(am__append_2) lsan asan ubsan \
-@SANITIZER_SUPPORTED_TRUE@	$(am__append_3)
+sanincludedir = $(libdir)/gcc/$(target_alias)/$(gcc_version)/include/sanitizer
+nodist_saninclude_HEADERS = $(am__append_1)
+@SANITIZER_SUPPORTED_TRUE@SUBDIRS = sanitizer_common $(am__append_2) \
+@SANITIZER_SUPPORTED_TRUE@	$(am__append_3) lsan asan ubsan \
+@SANITIZER_SUPPORTED_TRUE@	$(am__append_4)
 gcc_version := $(shell cat $(top_srcdir)/../gcc/BASE-VER)
 
 # Work around what appears to be a GNU make bug handling MAKEFLAGS
@@ -378,6 +384,26 @@ distclean-multi:
 	$(MULTICLEAN) $(AM_MAKEFLAGS) DO=distclean multi-clean # $(MAKE)
 maintainer-clean-multi:
 	$(MULTICLEAN) $(AM_MAKEFLAGS) DO=maintainer-clean multi-clean # $(MAKE)
+install-nodist_sanincludeHEADERS: $(nodist_saninclude_HEADERS)
+	@$(NORMAL_INSTALL)
+	test -z "$(sanincludedir)" || $(MKDIR_P) "$(DESTDIR)$(sanincludedir)"
+	@list='$(nodist_saninclude_HEADERS)'; test -n "$(sanincludedir)" || list=; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(sanincludedir)'"; \
+	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(sanincludedir)" || exit $$?; \
+	done
+
+uninstall-nodist_sanincludeHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(nodist_saninclude_HEADERS)'; test -n "$(sanincludedir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	test -n "$$files" || exit 0; \
+	echo " ( cd '$(DESTDIR)$(sanincludedir)' && rm -f" $$files ")"; \
+	cd "$(DESTDIR)$(sanincludedir)" && rm -f $$files
 install-nodist_toolexeclibHEADERS: $(nodist_toolexeclib_HEADERS)
 	@$(NORMAL_INSTALL)
 	test -z "$(toolexeclibdir)" || $(MKDIR_P) "$(DESTDIR)$(toolexeclibdir)"
@@ -538,7 +564,7 @@ check: check-recursive
 all-am: Makefile all-multi $(HEADERS) config.h
 installdirs: installdirs-recursive
 installdirs-am:
-	for dir in "$(DESTDIR)$(toolexeclibdir)"; do \
+	for dir in "$(DESTDIR)$(sanincludedir)" "$(DESTDIR)$(toolexeclibdir)"; do \
 	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
 	done
 install: install-recursive
@@ -588,7 +614,7 @@ info: info-recursive
 
 info-am:
 
-install-data-am:
+install-data-am: install-nodist_sanincludeHEADERS
 
 install-dvi: install-dvi-recursive
 
@@ -634,7 +660,8 @@ ps: ps-recursive
 
 ps-am:
 
-uninstall-am: uninstall-nodist_toolexeclibHEADERS
+uninstall-am: uninstall-nodist_sanincludeHEADERS \
+	uninstall-nodist_toolexeclibHEADERS
 
 .MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all all-multi \
 	clean-multi ctags-recursive distclean-multi install-am \
@@ -649,13 +676,14 @@ uninstall-am: uninstall-nodist_toolexeclibHEADERS
 	info-am install install-am install-data install-data-am \
 	install-dvi install-dvi-am install-exec install-exec-am \
 	install-html install-html-am install-info install-info-am \
-	install-man install-multi install-nodist_toolexeclibHEADERS \
-	install-pdf install-pdf-am install-ps install-ps-am \
-	install-strip installcheck installcheck-am installdirs \
-	installdirs-am maintainer-clean maintainer-clean-generic \
-	maintainer-clean-multi mostlyclean mostlyclean-generic \
-	mostlyclean-libtool mostlyclean-multi pdf pdf-am ps ps-am tags \
-	tags-recursive uninstall uninstall-am \
+	install-man install-multi install-nodist_sanincludeHEADERS \
+	install-nodist_toolexeclibHEADERS install-pdf install-pdf-am \
+	install-ps install-ps-am install-strip installcheck \
+	installcheck-am installdirs installdirs-am maintainer-clean \
+	maintainer-clean-generic maintainer-clean-multi mostlyclean \
+	mostlyclean-generic mostlyclean-libtool mostlyclean-multi pdf \
+	pdf-am ps ps-am tags tags-recursive uninstall uninstall-am \
+	uninstall-nodist_sanincludeHEADERS \
 	uninstall-nodist_toolexeclibHEADERS

^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH 3/17] Instrumentation of unaligned types
  2014-10-16  8:35 [PATCH 0/17] KASan 4.9 backport Yury Gribov
  2014-10-16  8:36 ` [PATCH 1/17] Install asan_interface.h Yury Gribov
@ 2014-10-16  8:36 ` Yury Gribov
  2014-10-16  8:45   ` Jakub Jelinek
  2014-10-16  8:37 ` [PATCH 4/17] Outline instrumentation Yury Gribov
                   ` (15 subsequent siblings)
  17 siblings, 1 reply; 49+ messages in thread
From: Yury Gribov @ 2014-10-16  8:36 UTC (permalink / raw)
  To: GCC Patches
  Cc: Jakub Jelinek, Dmitry Vyukov, Konstantin Khlebnikov,
	Andrey Ryabinin, Viacheslav Garbuzov

[-- Attachment #1: Type: text/plain, Size: 206 bytes --]

Further work on __asan_loadN/__asan_storeN. I removed the tests 
(misalign-1.c, misalign-2.c) because (as mentioned in comments for 
preceeding patch) __asan_loadN/__asan_storeN are disabled for userspace.

[-- Attachment #2: 0003-2014-10-15-Yury-Gribov-y.gribov-samsung.com.patch --]
[-- Type: text/x-patch, Size: 4472 bytes --]

2014-10-15  Yury Gribov  <y.gribov@samsung.com>

	Backport from mainline
 	2014-05-30  Jakub Jelinek  <jakub@redhat.com>

	* asan.c (report_error_func): Add SLOW_P argument, use
	BUILT_IN_ASAN_*_N if set.
	(build_check_stmt): Likewise.
	(instrument_derefs): If T has insufficient alignment,
	force same handling as for odd sizes.

diff --git a/gcc/asan.c b/gcc/asan.c
index 1bba680..820d8ef 100644
--- a/gcc/asan.c
+++ b/gcc/asan.c
@@ -1319,7 +1319,7 @@ asan_protect_global (tree decl)
    IS_STORE is either 1 (for a store) or 0 (for a load).  */
 
 static tree
-report_error_func (bool is_store, HOST_WIDE_INT size_in_bytes)
+report_error_func (bool is_store, HOST_WIDE_INT size_in_bytes, bool slow_p)
 {
   static enum built_in_function report[2][6]
     = { { BUILT_IN_ASAN_REPORT_LOAD1, BUILT_IN_ASAN_REPORT_LOAD2,
@@ -1329,7 +1329,8 @@ report_error_func (bool is_store, HOST_WIDE_INT size_in_bytes)
 	  BUILT_IN_ASAN_REPORT_STORE4, BUILT_IN_ASAN_REPORT_STORE8,
 	  BUILT_IN_ASAN_REPORT_STORE16, BUILT_IN_ASAN_REPORT_STORE_N } };
   if ((size_in_bytes & (size_in_bytes - 1)) != 0
-      || size_in_bytes > 16)
+      || size_in_bytes > 16
+      || slow_p)
     return builtin_decl_implicit (report[is_store][5]);
   return builtin_decl_implicit (report[is_store][exact_log2 (size_in_bytes)]);
 }
@@ -1508,7 +1509,8 @@ build_shadow_mem_access (gimple_stmt_iterator *gsi, location_t location,
 
 static void
 build_check_stmt (location_t location, tree base, gimple_stmt_iterator *iter,
-		  bool before_p, bool is_store, HOST_WIDE_INT size_in_bytes)
+		  bool before_p, bool is_store, HOST_WIDE_INT size_in_bytes,
+		  bool slow_p = false)
 {
   gimple_stmt_iterator gsi;
   basic_block then_bb, else_bb;
@@ -1522,9 +1524,15 @@ build_check_stmt (location_t location, tree base, gimple_stmt_iterator *iter,
   HOST_WIDE_INT real_size_in_bytes = size_in_bytes;
   tree sz_arg = NULL_TREE;
 
-  if ((size_in_bytes & (size_in_bytes - 1)) != 0
-      || size_in_bytes > 16)
-    real_size_in_bytes = 1;
+  if (size_in_bytes == 1)
+    slow_p = false;
+  else if ((size_in_bytes & (size_in_bytes - 1)) != 0
+	   || size_in_bytes > 16
+	   || slow_p)
+    {
+      real_size_in_bytes = 1;
+      slow_p = true;
+    }
 
   /* Get an iterator on the point where we can add the condition
      statement for the instrumentation.  */
@@ -1582,8 +1590,8 @@ build_check_stmt (location_t location, tree base, gimple_stmt_iterator *iter,
       t = gimple_assign_lhs (gimple_seq_last (seq));
       gimple_seq_set_location (seq, location);
       gsi_insert_seq_after (&gsi, seq, GSI_CONTINUE_LINKING);
-      /* For weird access sizes, check first and last byte.  */
-      if (real_size_in_bytes != size_in_bytes)
+      /* For weird access sizes or misaligned, check first and last byte.  */
+      if (slow_p)
 	{
 	  g = gimple_build_assign_with_ops (PLUS_EXPR,
 					    make_ssa_name (uintptr_type, NULL),
@@ -1626,7 +1634,7 @@ build_check_stmt (location_t location, tree base, gimple_stmt_iterator *iter,
 
   /* Generate call to the run-time library (e.g. __asan_report_load8).  */
   gsi = gsi_start_bb (then_bb);
-  g = gimple_build_call (report_error_func (is_store, size_in_bytes),
+  g = gimple_build_call (report_error_func (is_store, size_in_bytes, slow_p),
 			 sz_arg ? 2 : 1, base_addr, sz_arg);
   gimple_set_location (g, location);
   gsi_insert_after (&gsi, g, GSI_NEW_STMT);
@@ -1723,8 +1731,31 @@ instrument_derefs (gimple_stmt_iterator *iter, tree t,
   base = build_fold_addr_expr (t);
   if (!has_mem_ref_been_instrumented (base, size_in_bytes))
     {
+      bool slow_p = false;
+      if (size_in_bytes > 1)
+	{
+	  if ((size_in_bytes & (size_in_bytes - 1)) != 0
+	      || size_in_bytes > 16)
+	    slow_p = true;
+	  else
+	    {
+	      unsigned int align = get_object_alignment (t);
+	      if (align < size_in_bytes * BITS_PER_UNIT)
+		{
+		  /* On non-strict alignment targets, if
+		     16-byte access is just 8-byte aligned,
+		     this will result in misaligned shadow
+		     memory 2 byte load, but otherwise can
+		     be handled using one read.  */
+		  if (size_in_bytes != 16
+		      || STRICT_ALIGNMENT
+		      || align < 8 * BITS_PER_UNIT)
+		    slow_p = true;
+		}
+	    }
+	}
       build_check_stmt (location, base, iter, /*before_p=*/true,
-			is_store, size_in_bytes);
+			is_store, size_in_bytes, slow_p);
       update_mem_ref_hash_table (base, size_in_bytes);
       update_mem_ref_hash_table (t, size_in_bytes);
     }

^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH 4/17] Outline instrumentation
  2014-10-16  8:35 [PATCH 0/17] KASan 4.9 backport Yury Gribov
  2014-10-16  8:36 ` [PATCH 1/17] Install asan_interface.h Yury Gribov
  2014-10-16  8:36 ` [PATCH 3/17] Instrumentation of unaligned types Yury Gribov
@ 2014-10-16  8:37 ` Yury Gribov
  2014-10-16  8:46   ` Jakub Jelinek
  2014-10-16  8:37 ` [PATCH 2/17] Introduction of __asan_loadN/__asan_storeN Yury Gribov
                   ` (14 subsequent siblings)
  17 siblings, 1 reply; 49+ messages in thread
From: Yury Gribov @ 2014-10-16  8:37 UTC (permalink / raw)
  To: GCC Patches
  Cc: Jakub Jelinek, Dmitry Vyukov, Konstantin Khlebnikov,
	Andrey Ryabinin, Viacheslav Garbuzov

[-- Attachment #1: Type: text/plain, Size: 204 bytes --]

4.9's Asan runtime library provides no support for these so I removed 
the tests. I've also changed default value of threshold to INT_MAX to 
completely disable outline instrumentation in userspace Asan.

[-- Attachment #2: 0004-2014-10-15-Yury-Gribov-y.gribov-samsung.com.patch --]
[-- Type: text/x-patch, Size: 42074 bytes --]

New asan-instrumentation-with-call-threshold parameter.

2014-10-15  Yury Gribov  <y.gribov@samsung.com>

	Backport from mainline
	2014-06-16  Yury Gribov  <y.gribov@samsung.com>

	* asan.c (check_func): New function.
	(maybe_create_ssa_name): Likewise.
	(build_check_stmt_with_calls): Likewise.
	(use_calls_p): Likewise.
	(report_error_func): Change interface.
	(build_check_stmt): Allow non-integer lengths; add support
	for new parameter.
	(asan_instrument): Likewise.
	(instrument_mem_region_access): Moved code to
	build_check_stmt.
	(instrument_derefs): Likewise.
	(instrument_strlen_call): Likewise.
	* cfgcleanup.c (old_insns_match_p): Add support for new
	functions.
	* doc/invoke.texi: Describe new parameter.
	* params.def: Define new parameter.
	* params.h: Likewise.
	* sanitizer.def: Describe new builtins.

	* c-c++-common/asan/instrument-with-calls-1.c: New test.
	* c-c++-common/asan/instrument-with-calls-2.c: Likewise.
	* c-c++-common/asan/no-redundant-instrumentation-1.c: Update
	test patterns.
	* c-c++-common/asan/no-redundant-instrumentation-2.c:
	Likewise.
	* c-c++-common/asan/no-redundant-instrumentation-4.c:
	Likewise.
	* c-c++-common/asan/no-redundant-instrumentation-5.c:
	Likewise.
	* c-c++-common/asan/no-redundant-instrumentation-6.c:
	Likewise.
	* c-c++-common/asan/no-redundant-instrumentation-7.c:
	Likewise.
	* c-c++-common/asan/no-redundant-instrumentation-8.c:
	Likewise.

diff --git a/gcc/asan.c b/gcc/asan.c
index 820d8ef..5c091d0 100644
--- a/gcc/asan.c
+++ b/gcc/asan.c
@@ -242,6 +242,19 @@ static GTY(()) tree shadow_ptr_types[2];
 /* Decl for __asan_option_detect_stack_use_after_return.  */
 static GTY(()) tree asan_detect_stack_use_after_return;
 
+/* Number of instrumentations in current function so far.  */
+
+static int asan_num_accesses;
+
+/* Check whether we should replace inline instrumentation with calls.  */
+
+static inline bool
+use_calls_p ()
+{
+  return ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD < INT_MAX
+    && asan_num_accesses >= ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD;
+}
+
 /* Hashtable support for memory references used by gimple
    statements.  */
 
@@ -1319,7 +1332,7 @@ asan_protect_global (tree decl)
    IS_STORE is either 1 (for a store) or 0 (for a load).  */
 
 static tree
-report_error_func (bool is_store, HOST_WIDE_INT size_in_bytes, bool slow_p)
+report_error_func (bool is_store, HOST_WIDE_INT size_in_bytes, int *nargs)
 {
   static enum built_in_function report[2][6]
     = { { BUILT_IN_ASAN_REPORT_LOAD1, BUILT_IN_ASAN_REPORT_LOAD2,
@@ -1328,13 +1341,37 @@ report_error_func (bool is_store, HOST_WIDE_INT size_in_bytes, bool slow_p)
 	{ BUILT_IN_ASAN_REPORT_STORE1, BUILT_IN_ASAN_REPORT_STORE2,
 	  BUILT_IN_ASAN_REPORT_STORE4, BUILT_IN_ASAN_REPORT_STORE8,
 	  BUILT_IN_ASAN_REPORT_STORE16, BUILT_IN_ASAN_REPORT_STORE_N } };
-  if ((size_in_bytes & (size_in_bytes - 1)) != 0
-      || size_in_bytes > 16
-      || slow_p)
-    return builtin_decl_implicit (report[is_store][5]);
+  if (size_in_bytes == -1)
+    {
+      *nargs = 2;
+      return builtin_decl_implicit (report[is_store][5]);
+    }
+  *nargs = 1;
   return builtin_decl_implicit (report[is_store][exact_log2 (size_in_bytes)]);
 }
 
+/* Construct a function tree for __asan_{load,store}{1,2,4,8,16,_n}.
+   IS_STORE is either 1 (for a store) or 0 (for a load).  */
+
+static tree
+check_func (bool is_store, int size_in_bytes, int *nargs)
+{
+  static enum built_in_function check[2][6]
+    = { { BUILT_IN_ASAN_LOAD1, BUILT_IN_ASAN_LOAD2,
+      BUILT_IN_ASAN_LOAD4, BUILT_IN_ASAN_LOAD8,
+      BUILT_IN_ASAN_LOAD16, BUILT_IN_ASAN_LOADN },
+	{ BUILT_IN_ASAN_STORE1, BUILT_IN_ASAN_STORE2,
+      BUILT_IN_ASAN_STORE4, BUILT_IN_ASAN_STORE8,
+      BUILT_IN_ASAN_STORE16, BUILT_IN_ASAN_STOREN } };
+  if (size_in_bytes == -1)
+    {
+      *nargs = 2;
+      return builtin_decl_implicit (check[is_store][5]);
+    }
+  *nargs = 1;
+  return builtin_decl_implicit (check[is_store][exact_log2 (size_in_bytes)]);
+}
+
 /* Split the current basic block and create a condition statement
    insertion point right before or after the statement pointed to by
    ITER.  Return an iterator to the point at which the caller might
@@ -1494,6 +1531,76 @@ build_shadow_mem_access (gimple_stmt_iterator *gsi, location_t location,
   return gimple_assign_lhs (g);
 }
 
+/* BASE can already be an SSA_NAME; in that case, do not create a
+   new SSA_NAME for it.  */
+
+static tree
+maybe_create_ssa_name (location_t loc, tree base, gimple_stmt_iterator *iter,
+		       bool before_p)
+{
+  if (TREE_CODE (base) == SSA_NAME)
+    return base;
+  gimple g
+    = gimple_build_assign_with_ops (TREE_CODE (base),
+				    make_ssa_name (TREE_TYPE (base), NULL),
+				    base, NULL_TREE);
+  gimple_set_location (g, loc);
+  if (before_p)
+    gsi_insert_before (iter, g, GSI_SAME_STMT);
+  else
+    gsi_insert_after (iter, g, GSI_NEW_STMT);
+  return gimple_assign_lhs (g);
+}
+
+/* Instrument the memory access instruction using callbacks.
+   Parameters are similar to BUILD_CHECK_STMT.  */
+
+static void
+build_check_stmt_with_calls (location_t loc, tree base, tree len,
+			     HOST_WIDE_INT size_in_bytes, gimple_stmt_iterator *iter,
+			     bool before_p, bool is_store, bool is_scalar_access)
+{
+  gimple_stmt_iterator gsi = *iter;
+  tree base_ssa = maybe_create_ssa_name (loc, base, &gsi, before_p);
+
+  gimple g
+    = gimple_build_assign_with_ops (NOP_EXPR,
+				    make_ssa_name (pointer_sized_int_node, NULL),
+				    base_ssa, NULL_TREE);
+  gimple_set_location (g, loc);
+  if (before_p)
+    gsi_insert_before (&gsi, g, GSI_NEW_STMT);
+  else
+    gsi_insert_after (&gsi, g, GSI_NEW_STMT);
+  tree base_addr = gimple_assign_lhs (g);
+
+  int nargs;
+  tree fun
+    = check_func (is_store, is_scalar_access ? size_in_bytes : -1, &nargs);
+  if (nargs == 1)
+    g = gimple_build_call (fun, 1, base_addr);
+  else
+    {
+      gcc_assert (nargs == 2);
+      g = gimple_build_assign_with_ops (NOP_EXPR,
+					make_ssa_name (pointer_sized_int_node,
+						       NULL),
+					len, NULL_TREE);
+      gimple_set_location (g, loc);
+      gsi_insert_after (&gsi, g, GSI_NEW_STMT);
+      tree sz_arg = gimple_assign_lhs (g);
+      g = gimple_build_call (fun, nargs, base_addr, sz_arg);
+    }
+  gimple_set_location (g, loc);
+  gsi_insert_after (&gsi, g, GSI_NEW_STMT);
+
+  if (!before_p)
+    {
+      gsi_next (&gsi);
+      *iter = gsi;
+    }
+}
+
 /* Instrument the memory access instruction BASE.  Insert new
    statements before or after ITER.
 
@@ -1501,111 +1608,192 @@ build_shadow_mem_access (gimple_stmt_iterator *gsi, location_t location,
    SSA_NAME, or a non-SSA expression.  LOCATION is the source code
    location.  IS_STORE is TRUE for a store, FALSE for a load.
    BEFORE_P is TRUE for inserting the instrumentation code before
-   ITER, FALSE for inserting it after ITER.
+   ITER, FALSE for inserting it after ITER.  IS_SCALAR_ACCESS is TRUE
+   for a scalar memory access and FALSE for memory region access.
+   NON_ZERO_P is TRUE if memory region is guaranteed to have non-zero
+   length.  ALIGN tells alignment of accessed memory object.
+
+   START_INSTRUMENTED and END_INSTRUMENTED are TRUE if start/end of
+   memory region have already been instrumented.
 
    If BEFORE_P is TRUE, *ITER is arranged to still point to the
    statement it was pointing to prior to calling this function,
    otherwise, it points to the statement logically following it.  */
 
 static void
-build_check_stmt (location_t location, tree base, gimple_stmt_iterator *iter,
-		  bool before_p, bool is_store, HOST_WIDE_INT size_in_bytes,
-		  bool slow_p = false)
+build_check_stmt (location_t location, tree base, tree len,
+		  HOST_WIDE_INT size_in_bytes, gimple_stmt_iterator *iter,
+		  bool non_zero_len_p, bool before_p, bool is_store,
+		  bool is_scalar_access, unsigned int align = 0,
+		  bool start_instrumented = false,
+		  bool end_instrumented = false)
 {
-  gimple_stmt_iterator gsi;
-  basic_block then_bb, else_bb;
-  tree t, base_addr, shadow;
+  gimple_stmt_iterator gsi = *iter;
   gimple g;
-  tree shadow_ptr_type = shadow_ptr_types[size_in_bytes == 16 ? 1 : 0];
-  tree shadow_type = TREE_TYPE (shadow_ptr_type);
   tree uintptr_type
     = build_nonstandard_integer_type (TYPE_PRECISION (TREE_TYPE (base)), 1);
-  tree base_ssa = base;
-  HOST_WIDE_INT real_size_in_bytes = size_in_bytes;
-  tree sz_arg = NULL_TREE;
-
-  if (size_in_bytes == 1)
-    slow_p = false;
-  else if ((size_in_bytes & (size_in_bytes - 1)) != 0
-	   || size_in_bytes > 16
-	   || slow_p)
+
+  gcc_assert (!(size_in_bytes > 0 && !non_zero_len_p));
+
+  if (len)
+    len = unshare_expr (len);
+  else
+    {
+      gcc_assert (size_in_bytes != -1);
+      len = build_int_cst (pointer_sized_int_node, size_in_bytes);
+    }
+
+  if (size_in_bytes > 1)
     {
-      real_size_in_bytes = 1;
-      slow_p = true;
+      if ((size_in_bytes & (size_in_bytes - 1)) != 0
+	  || size_in_bytes > 16)
+	size_in_bytes = -1;
+      else if (align && align < size_in_bytes * BITS_PER_UNIT)
+	{
+	  /* On non-strict alignment targets, if
+	     16-byte access is just 8-byte aligned,
+	     this will result in misaligned shadow
+	     memory 2 byte load, but otherwise can
+	     be handled using one read.  */
+	  if (size_in_bytes != 16
+	      || STRICT_ALIGNMENT
+	      || align < 8 * BITS_PER_UNIT)
+	    size_in_bytes = -1;
+	}
+    }
+
+  HOST_WIDE_INT real_size_in_bytes = size_in_bytes == -1 ? 1 : size_in_bytes;
+
+  tree shadow_ptr_type = shadow_ptr_types[real_size_in_bytes == 16 ? 1 : 0];
+  tree shadow_type = TREE_TYPE (shadow_ptr_type);
+
+  base = unshare_expr (base);
+
+  if (use_calls_p ())
+    {
+      gsi = *iter;
+      build_check_stmt_with_calls (location, base, len, size_in_bytes, iter,
+				   before_p, is_store, is_scalar_access);
+      return;
+    }
+
+  ++asan_num_accesses;
+
+  if (!non_zero_len_p)
+    {
+      gcc_assert (before_p);
+
+      /* So, the length of the memory area to asan-protect is
+	 non-constant.  Let's guard the generated instrumentation code
+	 like:
+
+	 if (len != 0)
+	   {
+	     //asan instrumentation code goes here.
+	   }
+	 // falltrough instructions, starting with *ITER.  */
+
+      g = gimple_build_cond (NE_EXPR,
+			     len,
+			     build_int_cst (TREE_TYPE (len), 0),
+			     NULL_TREE, NULL_TREE);
+      gimple_set_location (g, location);
+
+      basic_block then_bb, fallthrough_bb;
+      insert_if_then_before_iter (g, iter, /*then_more_likely_p=*/true,
+				  &then_bb, &fallthrough_bb);
+      /* Note that fallthrough_bb starts with the statement that was
+	 pointed to by ITER.  */
+
+      /* The 'then block' of the 'if (len != 0) condition is where
+	 we'll generate the asan instrumentation code now.  */
+      gsi = gsi_last_bb (then_bb);
+      build_check_stmt (location, base, len, size_in_bytes, &gsi,
+			/*non_zero_len_p*/true, /*before_p*/true, is_store,
+			is_scalar_access, align,
+			start_instrumented, end_instrumented);
+      return;
     }
 
   /* Get an iterator on the point where we can add the condition
      statement for the instrumentation.  */
-  gsi = create_cond_insert_point (iter, before_p,
+  basic_block then_bb, else_bb;
+  gsi = create_cond_insert_point (&gsi, before_p,
 				  /*then_more_likely_p=*/false,
 				  /*create_then_fallthru_edge=*/false,
 				  &then_bb,
 				  &else_bb);
 
-  base = unshare_expr (base);
-
-  /* BASE can already be an SSA_NAME; in that case, do not create a
-     new SSA_NAME for it.  */
-  if (TREE_CODE (base) != SSA_NAME)
-    {
-      g = gimple_build_assign_with_ops (TREE_CODE (base),
-					make_ssa_name (TREE_TYPE (base), NULL),
-					base, NULL_TREE);
-      gimple_set_location (g, location);
-      gsi_insert_after (&gsi, g, GSI_NEW_STMT);
-      base_ssa = gimple_assign_lhs (g);
-    }
+  tree base_ssa = maybe_create_ssa_name (location, base, &gsi,
+					 /*before_p*/false);
 
   g = gimple_build_assign_with_ops (NOP_EXPR,
 				    make_ssa_name (uintptr_type, NULL),
 				    base_ssa, NULL_TREE);
   gimple_set_location (g, location);
   gsi_insert_after (&gsi, g, GSI_NEW_STMT);
-  base_addr = gimple_assign_lhs (g);
+  tree base_addr = gimple_assign_lhs (g);
 
-  /* Build
-     (base_addr >> ASAN_SHADOW_SHIFT) + targetm.asan_shadow_offset ().  */
-  shadow = build_shadow_mem_access (&gsi, location, base_addr,
-				    shadow_ptr_type);
-
-  if (real_size_in_bytes < 8)
+  tree t;
+  if (real_size_in_bytes >= 8)
+    {
+      tree shadow = build_shadow_mem_access (&gsi, location, base_addr,
+					     shadow_ptr_type);
+      t = shadow;
+    }
+  else
     {
-      /* Slow path for 1, 2 and 4 byte accesses.
-	 Test (shadow != 0)
-	      & ((base_addr & 7) + (real_size_in_bytes - 1)) >= shadow).  */
-      gimple_seq seq = NULL;
-      gimple shadow_test = build_assign (NE_EXPR, shadow, 0);
-      gimple_seq_add_stmt (&seq, shadow_test);
-      gimple_seq_add_stmt (&seq, build_assign (BIT_AND_EXPR, base_addr, 7));
-      gimple_seq_add_stmt (&seq, build_type_cast (shadow_type,
-                                                  gimple_seq_last (seq)));
-      if (real_size_in_bytes > 1)
-        gimple_seq_add_stmt (&seq,
-                             build_assign (PLUS_EXPR, gimple_seq_last (seq),
-					   real_size_in_bytes - 1));
-      gimple_seq_add_stmt (&seq, build_assign (GE_EXPR, gimple_seq_last (seq),
-                                               shadow));
-      gimple_seq_add_stmt (&seq, build_assign (BIT_AND_EXPR, shadow_test,
-                                               gimple_seq_last (seq)));
-      t = gimple_assign_lhs (gimple_seq_last (seq));
-      gimple_seq_set_location (seq, location);
-      gsi_insert_seq_after (&gsi, seq, GSI_CONTINUE_LINKING);
-      /* For weird access sizes or misaligned, check first and last byte.  */
-      if (slow_p)
+      /* Slow path for 1, 2 and 4 byte accesses.  */
+
+      if (!start_instrumented)
 	{
+	  /* Test (shadow != 0)
+		  & ((base_addr & 7) + (real_size_in_bytes - 1)) >= shadow).  */
+	  tree shadow = build_shadow_mem_access (&gsi, location, base_addr,
+						 shadow_ptr_type);
+	  gimple shadow_test = build_assign (NE_EXPR, shadow, 0);
+	  gimple_seq seq = NULL;
+	  gimple_seq_add_stmt (&seq, shadow_test);
+	  gimple_seq_add_stmt (&seq, build_assign (BIT_AND_EXPR, base_addr, 7));
+	  gimple_seq_add_stmt (&seq, build_type_cast (shadow_type,
+						      gimple_seq_last (seq)));
+	  if (real_size_in_bytes > 1)
+	    gimple_seq_add_stmt (&seq,
+				 build_assign (PLUS_EXPR, gimple_seq_last (seq),
+					       real_size_in_bytes - 1));
+	  gimple_seq_add_stmt (&seq, build_assign (GE_EXPR,
+						   gimple_seq_last (seq),
+						   shadow));
+	  gimple_seq_add_stmt (&seq, build_assign (BIT_AND_EXPR, shadow_test,
+						   gimple_seq_last (seq)));
+	  t = gimple_assign_lhs (gimple_seq_last (seq));
+	  gimple_seq_set_location (seq, location);
+	  gsi_insert_seq_after (&gsi, seq, GSI_CONTINUE_LINKING);
+	}
+
+      /* For non-constant, misaligned or otherwise weird access sizes,
+	 check first and last byte.  */
+      if (size_in_bytes == -1 && !end_instrumented)
+	{
+	  g = gimple_build_assign_with_ops (MINUS_EXPR,
+					    make_ssa_name (uintptr_type, NULL),
+					    len,
+					    build_int_cst (uintptr_type, 1));
+	  gimple_set_location (g, location);
+	  gsi_insert_after (&gsi, g, GSI_NEW_STMT);
+	  tree last = gimple_assign_lhs (g);
 	  g = gimple_build_assign_with_ops (PLUS_EXPR,
 					    make_ssa_name (uintptr_type, NULL),
 					    base_addr,
-					    build_int_cst (uintptr_type,
-							   size_in_bytes - 1));
+					    last);
 	  gimple_set_location (g, location);
 	  gsi_insert_after (&gsi, g, GSI_NEW_STMT);
 	  tree base_end_addr = gimple_assign_lhs (g);
 
-	  shadow = build_shadow_mem_access (&gsi, location, base_end_addr,
-					    shadow_ptr_type);
-	  seq = NULL;
-	  shadow_test = build_assign (NE_EXPR, shadow, 0);
+	  tree shadow = build_shadow_mem_access (&gsi, location, base_end_addr,
+						 shadow_ptr_type);
+	  gimple shadow_test = build_assign (NE_EXPR, shadow, 0);
+	  gimple_seq seq = NULL;
 	  gimple_seq_add_stmt (&seq, shadow_test);
 	  gimple_seq_add_stmt (&seq, build_assign (BIT_AND_EXPR,
 						   base_end_addr, 7));
@@ -1616,16 +1804,14 @@ build_check_stmt (location_t location, tree base, gimple_stmt_iterator *iter,
 						   shadow));
 	  gimple_seq_add_stmt (&seq, build_assign (BIT_AND_EXPR, shadow_test,
 						   gimple_seq_last (seq)));
-	  gimple_seq_add_stmt (&seq, build_assign (BIT_IOR_EXPR, t,
-						   gimple_seq_last (seq)));
+	  if (!start_instrumented)
+	    gimple_seq_add_stmt (&seq, build_assign (BIT_IOR_EXPR, t,
+						     gimple_seq_last (seq)));
 	  t = gimple_assign_lhs (gimple_seq_last (seq));
 	  gimple_seq_set_location (seq, location);
 	  gsi_insert_seq_after (&gsi, seq, GSI_CONTINUE_LINKING);
-	  sz_arg = build_int_cst (pointer_sized_int_node, size_in_bytes);
 	}
     }
-  else
-    t = shadow;
 
   g = gimple_build_cond (NE_EXPR, t, build_int_cst (TREE_TYPE (t), 0),
 			 NULL_TREE, NULL_TREE);
@@ -1634,8 +1820,23 @@ build_check_stmt (location_t location, tree base, gimple_stmt_iterator *iter,
 
   /* Generate call to the run-time library (e.g. __asan_report_load8).  */
   gsi = gsi_start_bb (then_bb);
-  g = gimple_build_call (report_error_func (is_store, size_in_bytes, slow_p),
-			 sz_arg ? 2 : 1, base_addr, sz_arg);
+  int nargs;
+  tree fun = report_error_func (is_store, is_scalar_access ? size_in_bytes : -1,
+				&nargs);
+  if (nargs == 1)
+      g = gimple_build_call (fun, 1, base_addr);
+  else
+    {
+      gcc_assert (nargs == 2);
+      g = gimple_build_assign_with_ops (NOP_EXPR,
+					make_ssa_name (pointer_sized_int_node,
+						       NULL),
+					len, NULL_TREE);
+      gimple_set_location (g, location);
+      gsi_insert_after (&gsi, g, GSI_NEW_STMT);
+      tree sz_arg = gimple_assign_lhs (g);
+      g = gimple_build_call (fun, nargs, base_addr, sz_arg);
+    }
   gimple_set_location (g, location);
   gsi_insert_after (&gsi, g, GSI_NEW_STMT);
 
@@ -1731,31 +1932,10 @@ instrument_derefs (gimple_stmt_iterator *iter, tree t,
   base = build_fold_addr_expr (t);
   if (!has_mem_ref_been_instrumented (base, size_in_bytes))
     {
-      bool slow_p = false;
-      if (size_in_bytes > 1)
-	{
-	  if ((size_in_bytes & (size_in_bytes - 1)) != 0
-	      || size_in_bytes > 16)
-	    slow_p = true;
-	  else
-	    {
-	      unsigned int align = get_object_alignment (t);
-	      if (align < size_in_bytes * BITS_PER_UNIT)
-		{
-		  /* On non-strict alignment targets, if
-		     16-byte access is just 8-byte aligned,
-		     this will result in misaligned shadow
-		     memory 2 byte load, but otherwise can
-		     be handled using one read.  */
-		  if (size_in_bytes != 16
-		      || STRICT_ALIGNMENT
-		      || align < 8 * BITS_PER_UNIT)
-		    slow_p = true;
-		}
-	    }
-	}
-      build_check_stmt (location, base, iter, /*before_p=*/true,
-			is_store, size_in_bytes, slow_p);
+      unsigned int align = get_object_alignment (t);
+      build_check_stmt (location, base, NULL_TREE, size_in_bytes, iter,
+			/*non_zero_len_p*/size_in_bytes > 0, /*before_p=*/true,
+			is_store, /*is_scalar_access*/true, align);
       update_mem_ref_hash_table (base, size_in_bytes);
       update_mem_ref_hash_table (t, size_in_bytes);
     }
@@ -1780,142 +1960,24 @@ instrument_mem_region_access (tree base, tree len,
       || integer_zerop (len))
     return;
 
-  gimple_stmt_iterator gsi = *iter;
-
-  basic_block fallthrough_bb = NULL, then_bb = NULL;
-
   /* If the beginning of the memory region has already been
      instrumented, do not instrument it.  */
   bool start_instrumented = has_mem_ref_been_instrumented (base, 1);
 
   /* If the end of the memory region has already been instrumented, do
-     not instrument it. */
+     not instrument it.  */
   tree end = asan_mem_ref_get_end (base, len);
   bool end_instrumented = has_mem_ref_been_instrumented (end, 1);
 
-  if (start_instrumented && end_instrumented)
-    return;
+  HOST_WIDE_INT size_in_bytes = tree_fits_shwi_p (len) ? tree_to_shwi (len) : -1;
 
-  if (!is_gimple_constant (len))
-    {
-      /* So, the length of the memory area to asan-protect is
-	 non-constant.  Let's guard the generated instrumentation code
-	 like:
+  build_check_stmt (location, base, len, size_in_bytes, iter,
+		    /*non_zero_len_p*/size_in_bytes > 0, /*before_p*/true,
+		    is_store, /*is_scalar_access*/false, /*align*/0,
+		    start_instrumented, end_instrumented);
 
-	 if (len != 0)
-	   {
-	     //asan instrumentation code goes here.
-	   }
-	   // falltrough instructions, starting with *ITER.  */
-
-      gimple g = gimple_build_cond (NE_EXPR,
-				    len,
-				    build_int_cst (TREE_TYPE (len), 0),
-				    NULL_TREE, NULL_TREE);
-      gimple_set_location (g, location);
-      insert_if_then_before_iter (g, iter, /*then_more_likely_p=*/true,
-				  &then_bb, &fallthrough_bb);
-      /* Note that fallthrough_bb starts with the statement that was
-	 pointed to by ITER.  */
-
-      /* The 'then block' of the 'if (len != 0) condition is where
-	 we'll generate the asan instrumentation code now.  */
-      gsi = gsi_last_bb (then_bb);
-    }
-
-  if (!start_instrumented)
-    {
-      /* Instrument the beginning of the memory region to be accessed,
-	 and arrange for the rest of the intrumentation code to be
-	 inserted in the then block *after* the current gsi.  */
-      build_check_stmt (location, base, &gsi, /*before_p=*/true, is_store, 1);
-
-      if (then_bb)
-	/* We are in the case where the length of the region is not
-	   constant; so instrumentation code is being generated in the
-	   'then block' of the 'if (len != 0) condition.  Let's arrange
-	   for the subsequent instrumentation statements to go in the
-	   'then block'.  */
-	gsi = gsi_last_bb (then_bb);
-      else
-        {
-          *iter = gsi;
-	  /* Don't remember this access as instrumented, if length
-	     is unknown.  It might be zero and not being actually
-	     instrumented, so we can't rely on it being instrumented.  */
-          update_mem_ref_hash_table (base, 1);
-	}
-    }
-
-  if (end_instrumented)
-    return;
-
-  /* We want to instrument the access at the end of the memory region,
-     which is at (base + len - 1).  */
-
-  /* offset = len - 1;  */
-  len = unshare_expr (len);
-  tree offset;
-  gimple_seq seq = NULL;
-  if (TREE_CODE (len) == INTEGER_CST)
-    offset = fold_build2 (MINUS_EXPR, size_type_node,
-			  fold_convert (size_type_node, len),
-			  build_int_cst (size_type_node, 1));
-  else
-    {
-      gimple g;
-      tree t;
-
-      if (TREE_CODE (len) != SSA_NAME)
-	{
-	  t = make_ssa_name (TREE_TYPE (len), NULL);
-	  g = gimple_build_assign_with_ops (TREE_CODE (len), t, len, NULL);
-	  gimple_set_location (g, location);
-	  gimple_seq_add_stmt_without_update (&seq, g);
-	  len = t;
-	}
-      if (!useless_type_conversion_p (size_type_node, TREE_TYPE (len)))
-	{
-	  t = make_ssa_name (size_type_node, NULL);
-	  g = gimple_build_assign_with_ops (NOP_EXPR, t, len, NULL);
-	  gimple_set_location (g, location);
-	  gimple_seq_add_stmt_without_update (&seq, g);
-	  len = t;
-	}
-
-      t = make_ssa_name (size_type_node, NULL);
-      g = gimple_build_assign_with_ops (MINUS_EXPR, t, len,
-					build_int_cst (size_type_node, 1));
-      gimple_set_location (g, location);
-      gimple_seq_add_stmt_without_update (&seq, g);
-      offset = gimple_assign_lhs (g);
-    }
-
-  /* _1 = base;  */
-  base = unshare_expr (base);
-  gimple region_end =
-    gimple_build_assign_with_ops (TREE_CODE (base),
-				  make_ssa_name (TREE_TYPE (base), NULL),
-				  base, NULL);
-  gimple_set_location (region_end, location);
-  gimple_seq_add_stmt_without_update (&seq, region_end);
-
-  /* _2 = _1 + offset;  */
-  region_end =
-    gimple_build_assign_with_ops (POINTER_PLUS_EXPR,
-				  make_ssa_name (TREE_TYPE (base), NULL),
-				  gimple_assign_lhs (region_end),
-				  offset);
-  gimple_set_location (region_end, location);
-  gimple_seq_add_stmt_without_update (&seq, region_end);
-  gsi_insert_seq_before (&gsi, seq, GSI_SAME_STMT);
-
-  /* instrument access at _2;  */
-  gsi = gsi_for_stmt (region_end);
-  build_check_stmt (location, gimple_assign_lhs (region_end),
-		    &gsi, /*before_p=*/false, is_store, 1);
-
-  if (then_bb == NULL)
+  update_mem_ref_hash_table (base, 1);
+  if (size_in_bytes != -1)
     update_mem_ref_hash_table (end, 1);
 
   *iter = gsi_for_stmt (gsi_stmt (*iter));
@@ -1957,47 +2019,30 @@ instrument_strlen_call (gimple_stmt_iterator *iter)
   location_t loc = gimple_location (call);
   tree str_arg = gimple_call_arg (call, 0);
 
-  /* Instrument the access to the first byte of str_arg.  i.e:
-
-     _1 = str_arg; instrument (_1); */
   tree cptr_type = build_pointer_type (char_type_node);
   gimple str_arg_ssa =
     gimple_build_assign_with_ops (NOP_EXPR,
 				  make_ssa_name (cptr_type, NULL),
 				  str_arg, NULL);
   gimple_set_location (str_arg_ssa, loc);
-  gimple_stmt_iterator gsi = *iter;
-  gsi_insert_before (&gsi, str_arg_ssa, GSI_NEW_STMT);
-  build_check_stmt (loc, gimple_assign_lhs (str_arg_ssa), &gsi,
-		    /*before_p=*/false, /*is_store=*/false, 1);
+  gsi_insert_before (iter, str_arg_ssa, GSI_SAME_STMT);
 
-  /* If we initially had an instruction like:
+  build_check_stmt (loc, gimple_assign_lhs (str_arg_ssa), NULL_TREE, 1, iter,
+		    /*non_zero_len_p*/true, /*before_p=*/true,
+		    /*is_store=*/false, /*is_scalar_access*/false, /*align*/0);
 
-	 int n = strlen (str)
-
-     we now want to instrument the access to str[n], after the
-     instruction above.*/
-
-  /* So let's build the access to str[n] that is, access through the
-     pointer_plus expr: (_1 + len).  */
   gimple stmt =
-    gimple_build_assign_with_ops (POINTER_PLUS_EXPR,
-				  make_ssa_name (cptr_type, NULL),
-				  gimple_assign_lhs (str_arg_ssa),
-				  len);
+    gimple_build_assign_with_ops (PLUS_EXPR,
+				  make_ssa_name (TREE_TYPE (len), NULL),
+				  len,
+				  build_int_cst (TREE_TYPE (len), 1));
   gimple_set_location (stmt, loc);
-  gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
-
-  build_check_stmt (loc, gimple_assign_lhs (stmt), &gsi,
-		    /*before_p=*/false, /*is_store=*/false, 1);
-
-  /* Ensure that iter points to the statement logically following the
-     one it was initially pointing to.  */
-  *iter = gsi;
-  /* As *ITER has been advanced to point to the next statement, let's
-     return true to inform transform_statements that it shouldn't
-     advance *ITER anymore; otherwises it will skip that next
-     statement, which wouldn't be instrumented.  */
+  gsi_insert_after (iter, stmt, GSI_NEW_STMT);
+
+  build_check_stmt (loc, gimple_assign_lhs (stmt), len, 1, iter,
+		    /*non_zero_len_p*/true, /*before_p=*/false,
+		    /*is_store=*/false, /*is_scalar_access*/false, /*align*/0);
+
   return true;
 }
 
@@ -2570,6 +2615,7 @@ asan_instrument (void)
 {
   if (shadow_ptr_types[0] == NULL_TREE)
     asan_init_shadow_ptr_types ();
+  asan_num_accesses = 0;
   transform_statements ();
   return 0;
 }
diff --git a/gcc/cfgcleanup.c b/gcc/cfgcleanup.c
index de307da..53ea300 100644
--- a/gcc/cfgcleanup.c
+++ b/gcc/cfgcleanup.c
@@ -1174,7 +1174,7 @@ old_insns_match_p (int mode ATTRIBUTE_UNUSED, rtx i1, rtx i2)
 		      && DECL_FUNCTION_CODE (SYMBOL_REF_DECL (symbol))
 			 >= BUILT_IN_ASAN_REPORT_LOAD1
 		      && DECL_FUNCTION_CODE (SYMBOL_REF_DECL (symbol))
-			 <= BUILT_IN_ASAN_REPORT_STORE16)
+			 <= BUILT_IN_ASAN_STOREN)
 		    return dir_none;
 		}
 	    }
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index a152472..4012f08 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -10134,6 +10134,12 @@ is enabled by default when using @option{-fsanitize=address} option.
 To disable use-after-return detection use 
 @option{--param asan-use-after-return=0}.
 
+@item asan-instrumentation-with-call-threshold
+Once number of memory accesses  in function becomes greater
+or equal than this number, use callbacks instead of
+generating inline code.  E.g. to disable inline code use
+@option{--param asan-instrumentation-with-call-threshold=0}.
+
 @end table
 @end table
 
diff --git a/gcc/params.def b/gcc/params.def
index dd2e2cd..a258c08 100644
--- a/gcc/params.def
+++ b/gcc/params.def
@@ -1084,6 +1084,12 @@ DEFPARAM (PARAM_ASAN_USE_AFTER_RETURN,
          "Enable asan builtin functions protection",
          1, 0, 1)
 
+DEFPARAM (PARAM_ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD,
+         "asan-instrumentation-with-call-threshold",
+         "Use callbacks instead of inline code once number of accesses "
+         " in function becomes greater or equal than this threshold",
+         INT_MAX, 0, INT_MAX)
+
 DEFPARAM (PARAM_UNINIT_CONTROL_DEP_ATTEMPTS,
 	  "uninit-control-dep-attempts",
 	  "Maximum number of nested calls to search for control dependencies "
diff --git a/gcc/params.h b/gcc/params.h
index 0d6daa2..d488e32 100644
--- a/gcc/params.h
+++ b/gcc/params.h
@@ -232,5 +232,7 @@ extern void init_param_values (int *params);
   PARAM_VALUE (PARAM_ASAN_MEMINTRIN)
 #define ASAN_USE_AFTER_RETURN \
   PARAM_VALUE (PARAM_ASAN_USE_AFTER_RETURN)
+#define ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD \
+  PARAM_VALUE (PARAM_ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD)
 
 #endif /* ! GCC_PARAMS_H */
diff --git a/gcc/sanitizer.def b/gcc/sanitizer.def
index 0bb4682a..b1e6f04 100644
--- a/gcc/sanitizer.def
+++ b/gcc/sanitizer.def
@@ -29,7 +29,7 @@ along with GCC; see the file COPYING3.  If not see
 /* Address Sanitizer */
 DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_INIT, "__asan_init_v3",
 		      BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST)
-/* Do not reorder the BUILT_IN_ASAN_REPORT* builtins, e.g. cfgcleanup.c
+/* Do not reorder the BUILT_IN_ASAN_{REPORT,CHECK}* builtins, e.g. cfgcleanup.c
    relies on this order.  */
 DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_REPORT_LOAD1, "__asan_report_load1",
 		      BT_FN_VOID_PTR, ATTR_TMPURE_NORETURN_NOTHROW_LEAF_LIST)
@@ -57,6 +57,30 @@ DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_REPORT_STORE16, "__asan_report_store16",
 DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_REPORT_STORE_N, "__asan_report_store_n",
 		      BT_FN_VOID_PTR_PTRMODE,
 		      ATTR_TMPURE_NORETURN_NOTHROW_LEAF_LIST)
+DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_LOAD1, "__asan_load1",
+		      BT_FN_VOID_PTR, ATTR_TMPURE_NOTHROW_LEAF_LIST)
+DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_LOAD2, "__asan_load2",
+		      BT_FN_VOID_PTR, ATTR_TMPURE_NOTHROW_LEAF_LIST)
+DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_LOAD4, "__asan_load4",
+		      BT_FN_VOID_PTR, ATTR_TMPURE_NOTHROW_LEAF_LIST)
+DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_LOAD8, "__asan_load8",
+		      BT_FN_VOID_PTR, ATTR_TMPURE_NOTHROW_LEAF_LIST)
+DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_LOAD16, "__asan_load16",
+		      BT_FN_VOID_PTR, ATTR_TMPURE_NOTHROW_LEAF_LIST)
+DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_LOADN, "__asan_loadN",
+		      BT_FN_VOID_PTR_PTRMODE, ATTR_TMPURE_NOTHROW_LEAF_LIST)
+DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_STORE1, "__asan_store1",
+		      BT_FN_VOID_PTR, ATTR_TMPURE_NOTHROW_LEAF_LIST)
+DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_STORE2, "__asan_store2",
+		      BT_FN_VOID_PTR, ATTR_TMPURE_NOTHROW_LEAF_LIST)
+DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_STORE4, "__asan_store4",
+		      BT_FN_VOID_PTR, ATTR_TMPURE_NOTHROW_LEAF_LIST)
+DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_STORE8, "__asan_store8",
+		      BT_FN_VOID_PTR, ATTR_TMPURE_NOTHROW_LEAF_LIST)
+DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_STORE16, "__asan_store16",
+		      BT_FN_VOID_PTR, ATTR_TMPURE_NOTHROW_LEAF_LIST)
+DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_STOREN, "__asan_storeN",
+		      BT_FN_VOID_PTR_PTRMODE, ATTR_TMPURE_NOTHROW_LEAF_LIST)
 DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_REGISTER_GLOBALS,
 		      "__asan_register_globals",
 		      BT_FN_VOID_PTR_PTRMODE, ATTR_NOTHROW_LEAF_LIST)
diff --git a/gcc/testsuite/c-c++-common/asan/instrument-with-calls-1.c b/gcc/testsuite/c-c++-common/asan/instrument-with-calls-1.c
new file mode 100644
index 0000000..80f7620
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/asan/instrument-with-calls-1.c
@@ -0,0 +1,10 @@
+/* { dg-do assemble } */
+/* { dg-options "--param asan-instrumentation-with-call-threshold=0 -save-temps" } */
+
+void f(char *a, int *b) {
+  *b = *a;
+}
+
+/* { dg-final { scan-assembler "__asan_load1" } } */
+/* { dg-final { scan-assembler "__asan_store4" } } */
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/c-c++-common/asan/instrument-with-calls-2.c b/gcc/testsuite/c-c++-common/asan/instrument-with-calls-2.c
new file mode 100644
index 0000000..570f796
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/asan/instrument-with-calls-2.c
@@ -0,0 +1,16 @@
+/* { dg-do assemble } */
+/* { dg-options "--param asan-instrumentation-with-call-threshold=1 -save-temps" } */
+
+int x;
+
+void f(int *a, int *b) {
+  *a = 0;
+  asm volatile ("" ::: "memory");
+  x = *b;
+}
+
+/* { dg-final { scan-assembler-not "__asan_store4" } } */
+/* { dg-final { scan-assembler "__asan_report_store4" } } */
+/* { dg-final { scan-assembler "__asan_load4" } } */
+/* { dg-final { scan-assembler-not "__asan_report_load4" } } */
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-1.c b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-1.c
index fa52e0c..c7c594e 100644
--- a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-1.c
+++ b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-1.c
@@ -16,12 +16,11 @@ test0 ()
   tab[0] = 1;
   tab[1] = 2;
 
-  /* __builtin___asan_report_load1 called 1 time for the store
-     below.  */
-  char t0 = tab[1];
-
   /* This load should not be instrumented because it is to the same
      memory location as above.  */
+  char t0 = tab[1];
+
+  /* Likewise.  */
   char t1 = tab[1];
 
   return t0 + t1;
@@ -36,7 +35,7 @@ test1 (int i)
     the initialization.  */
   foo[i] = 1;
 
-  /*__builtin___asan_report_store1 called 2 times here to instrument
+  /*__builtin___asan_report_store_n called once here to instrument
     the store to the memory region of tab.  */
   __builtin_memset (tab, 3, sizeof (tab));
 
@@ -44,8 +43,8 @@ test1 (int i)
   __builtin_memset (tab, 4, sizeof (tab));
   __builtin_memset (tab, 5, sizeof (tab));
 
-  /* There are 2 calls to __builtin___asan_report_store1 and 2 calls
-     to __builtin___asan_report_load1 to instrument the store to
+  /* There is a call to __builtin___asan_report_store_n and a call
+     to __builtin___asan_report_load_n to instrument the store to
      (subset of) the memory region of tab.  */
   __builtin_memcpy (&tab[1], foo + i, 3);
 
@@ -53,7 +52,7 @@ test1 (int i)
      the reference to tab[1] has been already instrumented above.  */
   return tab[1];
 
-  /* So for these function, there should be 7 calls to
+  /* So for these functions, there should be 3 calls to
      __builtin___asan_report_store1.  */
 }
 
@@ -63,6 +62,7 @@ main ()
   return test0 () && test1 (0);
 }
 
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store1" 7 "asan0" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load" 2 "asan0" }  } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store1" 3 "asan0" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store_n" 2 "asan0" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load" 1 "asan0" }  } */
 /* { dg-final { cleanup-tree-dump "asan0" } } */
diff --git a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-2.c b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-2.c
index 28525e0..143312f 100644
--- a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-2.c
+++ b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-2.c
@@ -20,6 +20,7 @@ main ()
   __builtin_memset (tab, 1, 3);
 }
 
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store1" 3 "asan0" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report" 3 "asan0" }  } */
+/* { dg-final { scan-tree-dump-times "& 7" 3 "asan0" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store_n" 2 "asan0" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report" 2 "asan0" }  } */
 /* { dg-final { cleanup-tree-dump "asan0" } } */
diff --git a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-4.c b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-4.c
index b2e7284..da91cd5 100644
--- a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-4.c
+++ b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-4.c
@@ -5,9 +5,13 @@
 void
 foo  (int *a, char *b, char *c)
 {
+  /* One check for c[0], one check for a[], one check for c, two checks for b.  */
   __builtin_memmove (c, b, a[c[0]]);
+  /* For a total of 5 checks.  */
 }
 
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load1" 3 "asan0" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store1" 1 "asan0" } } */
+/* { dg-final { scan-tree-dump-times "& 7" 5 "asan0" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load1" 1 "asan0" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load_n" 1 "asan0" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store_n" 1 "asan0" } } */
 /* { dg-final { cleanup-tree-dump "asan0" } } */
diff --git a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-5.c b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-5.c
index ead3f58..134be66 100644
--- a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-5.c
+++ b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-5.c
@@ -5,9 +5,14 @@
 void
 foo  (int *a, char *b, char *c)
 {
+  /* One check for b[0], one check for a[], 2 checks for c and one checks for b.  */
   __builtin_memmove (c, b, a[b[0]]);
+  /* For a total of 5 checks.  */
 }
 
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load1" 2 "asan0" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store1" 2 "asan0" } } */
+/* { dg-final { scan-tree-dump-times "& 7" 5 "asan0" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load1" 1 "asan0" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load4" 1 "asan0" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load_n" 1 "asan0" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store_n" 1 "asan0" } } */
 /* { dg-final { cleanup-tree-dump "asan0" } } */
diff --git a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-6.c b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-6.c
index e4691bc..55c8ee3 100644
--- a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-6.c
+++ b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-6.c
@@ -5,10 +5,16 @@
 void
 foo  (int *a, char *b, char *c)
 {
+  /* One check for c[0], one check for a[], one check for c and 2 checks for b.  */
   __builtin_memmove (c, b, a[c[0]]);
+  /* One check for a[], one check for c and one check for b.  */
   __builtin_memmove (c, b, a[b[0]]);
+  /* For a total of 8 checks.  */
 }
 
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load1" 5 "asan0" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store1" 2 "asan0" } } */
+/* { dg-final { scan-tree-dump-times "& 7" 8 "asan0" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load1" 1 "asan0" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load4" 2 "asan0" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load_n" 2 "asan0" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store_n" 2 "asan0" } } */
 /* { dg-final { cleanup-tree-dump "asan0" } } */
diff --git a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-7.c b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-7.c
index bf40a03..a04956d 100644
--- a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-7.c
+++ b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-7.c
@@ -13,11 +13,15 @@ struct S
 int
 foo  (int *a, char *b, char *c)
 {
+  /* 2 checks for s.a, 2 checks for e.  */
   int d = __builtin_memcmp (s.a, e, 100);
+  /* One check for s.a and one check for e.  */
   d += __builtin_memcmp (s.a, e, 200);
+  /* For a total of 6 checks.  */
   return d;
 }
 
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load" 6 "asan0" } } */
+/* { dg-final { scan-tree-dump-times "& 7" 6 "asan0" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load_n" 4 "asan0" } } */
 /* { dg-final { scan-tree-dump-not "__builtin___asan_report_store" "asan0" } } */
 /* { dg-final { cleanup-tree-dump "asan0" } } */
diff --git a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-8.c b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-8.c
index 38ea7a2..308a133 100644
--- a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-8.c
+++ b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-8.c
@@ -5,10 +5,16 @@
 char
 foo  (int *a, char *b, char *c)
 {
+  /* One check for b[0], one check for a[], two checks for c and one check for b.  */
   __builtin_memmove (c, b, a[b[0]]);
+  /* No checks here.  */
   return c[0] + b[0];
+  /* For a total of 5 checks.  */
 }
 
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load1" 3 "asan0" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store1" 2 "asan0" } } */
+/* { dg-final { scan-tree-dump-times "& 7" 5 "asan0" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load1" 1 "asan0" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load4" 1 "asan0" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load_n" 1 "asan0" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store_n" 1 "asan0" } } */
 /* { dg-final { cleanup-tree-dump "asan0" } } */

^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH 2/17] Introduction of __asan_loadN/__asan_storeN
  2014-10-16  8:35 [PATCH 0/17] KASan 4.9 backport Yury Gribov
                   ` (2 preceding siblings ...)
  2014-10-16  8:37 ` [PATCH 4/17] Outline instrumentation Yury Gribov
@ 2014-10-16  8:37 ` Yury Gribov
  2014-10-16  8:44   ` Jakub Jelinek
  2014-10-16  8:38 ` [PATCH 6/17] Fix for PR 61530 Yury Gribov
                   ` (13 subsequent siblings)
  17 siblings, 1 reply; 49+ messages in thread
From: Yury Gribov @ 2014-10-16  8:37 UTC (permalink / raw)
  To: GCC Patches
  Cc: Jakub Jelinek, Dmitry Vyukov, Konstantin Khlebnikov,
	Andrey Ryabinin, Viacheslav Garbuzov

[-- Attachment #1: Type: text/plain, Size: 158 bytes --]

I disabled __asan_loadN/__asan_storeN because 4.9's Asan runtime doesn't 
support them. In a later patch I re-enable these functions specifically 
for KAsan.

[-- Attachment #2: 0002-2014-10-15-Yury-Gribov-y.gribov-samsung.com.patch --]
[-- Type: text/x-patch, Size: 14298 bytes --]

2014-10-15  Yury Gribov  <y.gribov@samsung.com>

	Backport from mainline
	2014-05-30  Jakub Jelinek  <jakub@redhat.com>

	* sanitizer.def (BUILT_IN_ASAN_REPORT_LOAD_N,
	BUILT_IN_ASAN_REPORT_STORE_N): New.
	* asan.c (struct asan_mem_ref): Change access_size type to
	HOST_WIDE_INT.
	(asan_mem_ref_init, asan_mem_ref_new, get_mem_refs_of_builtin_call,
	update_mem_ref_hash_table): Likewise.
	(asan_mem_ref_hasher::hash): Hash in a HWI.
	(report_error_func): Change size_in_bytes argument to HWI.
	Use *_N builtins if size_in_bytes is larger than 16 or not power of
	two.
	(build_shadow_mem_access): New function.
	(build_check_stmt): Use it.  Change size_in_bytes argument to HWI.
	Handle size_in_bytes not power of two or larger than 16.
	(instrument_derefs): Don't give up if size_in_bytes is not
	power of two or is larger than 16.

diff --git a/gcc/asan.c b/gcc/asan.c
index 08cc2c0..1bba680 100644
--- a/gcc/asan.c
+++ b/gcc/asan.c
@@ -251,8 +251,8 @@ struct asan_mem_ref
   /* The expression of the beginning of the memory region.  */
   tree start;
 
-  /* The size of the access (can be 1, 2, 4, 8, 16 for now).  */
-  char access_size;
+  /* The size of the access.  */
+  HOST_WIDE_INT access_size;
 };
 
 static alloc_pool asan_mem_ref_alloc_pool;
@@ -274,7 +274,7 @@ asan_mem_ref_get_alloc_pool ()
 /* Initializes an instance of asan_mem_ref.  */
 
 static void
-asan_mem_ref_init (asan_mem_ref *ref, tree start, char access_size)
+asan_mem_ref_init (asan_mem_ref *ref, tree start, HOST_WIDE_INT access_size)
 {
   ref->start = start;
   ref->access_size = access_size;
@@ -287,7 +287,7 @@ asan_mem_ref_init (asan_mem_ref *ref, tree start, char access_size)
    access to the referenced memory.  */
 
 static asan_mem_ref*
-asan_mem_ref_new (tree start, char access_size)
+asan_mem_ref_new (tree start, HOST_WIDE_INT access_size)
 {
   asan_mem_ref *ref =
     (asan_mem_ref *) pool_alloc (asan_mem_ref_get_alloc_pool ());
@@ -334,7 +334,7 @@ inline hashval_t
 asan_mem_ref_hasher::hash (const asan_mem_ref *mem_ref)
 {
   hashval_t h = iterative_hash_expr (mem_ref->start, 0);
-  h = iterative_hash_hashval_t (h, mem_ref->access_size);
+  h = iterative_hash_host_wide_int (mem_ref->access_size, h);
   return h;
 }
 
@@ -392,7 +392,7 @@ free_mem_ref_resources ()
 /* Return true iff the memory reference REF has been instrumented.  */
 
 static bool
-has_mem_ref_been_instrumented (tree ref, char access_size)
+has_mem_ref_been_instrumented (tree ref, HOST_WIDE_INT access_size)
 {
   asan_mem_ref r;
   asan_mem_ref_init (&r, ref, access_size);
@@ -480,7 +480,7 @@ get_mem_refs_of_builtin_call (const gimple call,
   tree source0 = NULL_TREE, source1 = NULL_TREE,
     dest = NULL_TREE, len = NULL_TREE;
   bool is_store = true, got_reference_p = false;
-  char access_size = 1;
+  HOST_WIDE_INT access_size = 1;
 
   switch (DECL_FUNCTION_CODE (callee))
     {
@@ -842,7 +842,7 @@ has_stmt_been_instrumented_p (gimple stmt)
 /*  Insert a memory reference into the hash table.  */
 
 static void
-update_mem_ref_hash_table (tree ref, char access_size)
+update_mem_ref_hash_table (tree ref, HOST_WIDE_INT access_size)
 {
   hash_table <asan_mem_ref_hasher> ht = get_mem_ref_hash_table ();
 
@@ -1315,20 +1315,22 @@ asan_protect_global (tree decl)
   return true;
 }
 
-/* Construct a function tree for __asan_report_{load,store}{1,2,4,8,16}.
-   IS_STORE is either 1 (for a store) or 0 (for a load).
-   SIZE_IN_BYTES is one of 1, 2, 4, 8, 16.  */
+/* Construct a function tree for __asan_report_{load,store}{1,2,4,8,16,_n}.
+   IS_STORE is either 1 (for a store) or 0 (for a load).  */
 
 static tree
-report_error_func (bool is_store, int size_in_bytes)
+report_error_func (bool is_store, HOST_WIDE_INT size_in_bytes)
 {
-  static enum built_in_function report[2][5]
+  static enum built_in_function report[2][6]
     = { { BUILT_IN_ASAN_REPORT_LOAD1, BUILT_IN_ASAN_REPORT_LOAD2,
 	  BUILT_IN_ASAN_REPORT_LOAD4, BUILT_IN_ASAN_REPORT_LOAD8,
-	  BUILT_IN_ASAN_REPORT_LOAD16 },
+	  BUILT_IN_ASAN_REPORT_LOAD16, BUILT_IN_ASAN_REPORT_LOAD_N },
 	{ BUILT_IN_ASAN_REPORT_STORE1, BUILT_IN_ASAN_REPORT_STORE2,
 	  BUILT_IN_ASAN_REPORT_STORE4, BUILT_IN_ASAN_REPORT_STORE8,
-	  BUILT_IN_ASAN_REPORT_STORE16 } };
+	  BUILT_IN_ASAN_REPORT_STORE16, BUILT_IN_ASAN_REPORT_STORE_N } };
+  if ((size_in_bytes & (size_in_bytes - 1)) != 0
+      || size_in_bytes > 16)
+    return builtin_decl_implicit (report[is_store][5]);
   return builtin_decl_implicit (report[is_store][exact_log2 (size_in_bytes)]);
 }
 
@@ -1450,6 +1452,47 @@ insert_if_then_before_iter (gimple cond,
   gsi_insert_after (&cond_insert_point, cond, GSI_NEW_STMT);
 }
 
+/* Build
+   (base_addr >> ASAN_SHADOW_SHIFT) + targetm.asan_shadow_offset ().  */
+
+static tree
+build_shadow_mem_access (gimple_stmt_iterator *gsi, location_t location,
+			 tree base_addr, tree shadow_ptr_type)
+{
+  tree t, uintptr_type = TREE_TYPE (base_addr);
+  tree shadow_type = TREE_TYPE (shadow_ptr_type);
+  gimple g;
+
+  t = build_int_cst (uintptr_type, ASAN_SHADOW_SHIFT);
+  g = gimple_build_assign_with_ops (RSHIFT_EXPR,
+				    make_ssa_name (uintptr_type, NULL),
+				    base_addr, t);
+  gimple_set_location (g, location);
+  gsi_insert_after (gsi, g, GSI_NEW_STMT);
+
+  t = build_int_cst (uintptr_type, targetm.asan_shadow_offset ());
+  g = gimple_build_assign_with_ops (PLUS_EXPR,
+				    make_ssa_name (uintptr_type, NULL),
+				    gimple_assign_lhs (g), t);
+  gimple_set_location (g, location);
+  gsi_insert_after (gsi, g, GSI_NEW_STMT);
+
+  g = gimple_build_assign_with_ops (NOP_EXPR,
+				    make_ssa_name (shadow_ptr_type, NULL),
+				    gimple_assign_lhs (g), NULL_TREE);
+  gimple_set_location (g, location);
+  gsi_insert_after (gsi, g, GSI_NEW_STMT);
+
+  t = build2 (MEM_REF, shadow_type, gimple_assign_lhs (g),
+	      build_int_cst (shadow_ptr_type, 0));
+  g = gimple_build_assign_with_ops (MEM_REF,
+				    make_ssa_name (shadow_type, NULL),
+				    t, NULL_TREE);
+  gimple_set_location (g, location);
+  gsi_insert_after (gsi, g, GSI_NEW_STMT);
+  return gimple_assign_lhs (g);
+}
+
 /* Instrument the memory access instruction BASE.  Insert new
    statements before or after ITER.
 
@@ -1457,8 +1500,7 @@ insert_if_then_before_iter (gimple cond,
    SSA_NAME, or a non-SSA expression.  LOCATION is the source code
    location.  IS_STORE is TRUE for a store, FALSE for a load.
    BEFORE_P is TRUE for inserting the instrumentation code before
-   ITER, FALSE for inserting it after ITER.  SIZE_IN_BYTES is one of
-   1, 2, 4, 8, 16.
+   ITER, FALSE for inserting it after ITER.
 
    If BEFORE_P is TRUE, *ITER is arranged to still point to the
    statement it was pointing to prior to calling this function,
@@ -1466,7 +1508,7 @@ insert_if_then_before_iter (gimple cond,
 
 static void
 build_check_stmt (location_t location, tree base, gimple_stmt_iterator *iter,
-		  bool before_p, bool is_store, int size_in_bytes)
+		  bool before_p, bool is_store, HOST_WIDE_INT size_in_bytes)
 {
   gimple_stmt_iterator gsi;
   basic_block then_bb, else_bb;
@@ -1477,6 +1519,12 @@ build_check_stmt (location_t location, tree base, gimple_stmt_iterator *iter,
   tree uintptr_type
     = build_nonstandard_integer_type (TYPE_PRECISION (TREE_TYPE (base)), 1);
   tree base_ssa = base;
+  HOST_WIDE_INT real_size_in_bytes = size_in_bytes;
+  tree sz_arg = NULL_TREE;
+
+  if ((size_in_bytes & (size_in_bytes - 1)) != 0
+      || size_in_bytes > 16)
+    real_size_in_bytes = 1;
 
   /* Get an iterator on the point where we can add the condition
      statement for the instrumentation.  */
@@ -1509,51 +1557,24 @@ build_check_stmt (location_t location, tree base, gimple_stmt_iterator *iter,
 
   /* Build
      (base_addr >> ASAN_SHADOW_SHIFT) + targetm.asan_shadow_offset ().  */
+  shadow = build_shadow_mem_access (&gsi, location, base_addr,
+				    shadow_ptr_type);
 
-  t = build_int_cst (uintptr_type, ASAN_SHADOW_SHIFT);
-  g = gimple_build_assign_with_ops (RSHIFT_EXPR,
-				    make_ssa_name (uintptr_type, NULL),
-				    base_addr, t);
-  gimple_set_location (g, location);
-  gsi_insert_after (&gsi, g, GSI_NEW_STMT);
-
-  t = build_int_cst (uintptr_type, targetm.asan_shadow_offset ());
-  g = gimple_build_assign_with_ops (PLUS_EXPR,
-				    make_ssa_name (uintptr_type, NULL),
-				    gimple_assign_lhs (g), t);
-  gimple_set_location (g, location);
-  gsi_insert_after (&gsi, g, GSI_NEW_STMT);
-
-  g = gimple_build_assign_with_ops (NOP_EXPR,
-				    make_ssa_name (shadow_ptr_type, NULL),
-				    gimple_assign_lhs (g), NULL_TREE);
-  gimple_set_location (g, location);
-  gsi_insert_after (&gsi, g, GSI_NEW_STMT);
-
-  t = build2 (MEM_REF, shadow_type, gimple_assign_lhs (g),
-	      build_int_cst (shadow_ptr_type, 0));
-  g = gimple_build_assign_with_ops (MEM_REF,
-				    make_ssa_name (shadow_type, NULL),
-				    t, NULL_TREE);
-  gimple_set_location (g, location);
-  gsi_insert_after (&gsi, g, GSI_NEW_STMT);
-  shadow = gimple_assign_lhs (g);
-
-  if (size_in_bytes < 8)
+  if (real_size_in_bytes < 8)
     {
       /* Slow path for 1, 2 and 4 byte accesses.
 	 Test (shadow != 0)
-	      & ((base_addr & 7) + (size_in_bytes - 1)) >= shadow).  */
+	      & ((base_addr & 7) + (real_size_in_bytes - 1)) >= shadow).  */
       gimple_seq seq = NULL;
       gimple shadow_test = build_assign (NE_EXPR, shadow, 0);
       gimple_seq_add_stmt (&seq, shadow_test);
       gimple_seq_add_stmt (&seq, build_assign (BIT_AND_EXPR, base_addr, 7));
       gimple_seq_add_stmt (&seq, build_type_cast (shadow_type,
                                                   gimple_seq_last (seq)));
-      if (size_in_bytes > 1)
+      if (real_size_in_bytes > 1)
         gimple_seq_add_stmt (&seq,
                              build_assign (PLUS_EXPR, gimple_seq_last (seq),
-                                           size_in_bytes - 1));
+					   real_size_in_bytes - 1));
       gimple_seq_add_stmt (&seq, build_assign (GE_EXPR, gimple_seq_last (seq),
                                                shadow));
       gimple_seq_add_stmt (&seq, build_assign (BIT_AND_EXPR, shadow_test,
@@ -1561,6 +1582,39 @@ build_check_stmt (location_t location, tree base, gimple_stmt_iterator *iter,
       t = gimple_assign_lhs (gimple_seq_last (seq));
       gimple_seq_set_location (seq, location);
       gsi_insert_seq_after (&gsi, seq, GSI_CONTINUE_LINKING);
+      /* For weird access sizes, check first and last byte.  */
+      if (real_size_in_bytes != size_in_bytes)
+	{
+	  g = gimple_build_assign_with_ops (PLUS_EXPR,
+					    make_ssa_name (uintptr_type, NULL),
+					    base_addr,
+					    build_int_cst (uintptr_type,
+							   size_in_bytes - 1));
+	  gimple_set_location (g, location);
+	  gsi_insert_after (&gsi, g, GSI_NEW_STMT);
+	  tree base_end_addr = gimple_assign_lhs (g);
+
+	  shadow = build_shadow_mem_access (&gsi, location, base_end_addr,
+					    shadow_ptr_type);
+	  seq = NULL;
+	  shadow_test = build_assign (NE_EXPR, shadow, 0);
+	  gimple_seq_add_stmt (&seq, shadow_test);
+	  gimple_seq_add_stmt (&seq, build_assign (BIT_AND_EXPR,
+						   base_end_addr, 7));
+	  gimple_seq_add_stmt (&seq, build_type_cast (shadow_type,
+						      gimple_seq_last (seq)));
+	  gimple_seq_add_stmt (&seq, build_assign (GE_EXPR,
+						   gimple_seq_last (seq),
+						   shadow));
+	  gimple_seq_add_stmt (&seq, build_assign (BIT_AND_EXPR, shadow_test,
+						   gimple_seq_last (seq)));
+	  gimple_seq_add_stmt (&seq, build_assign (BIT_IOR_EXPR, t,
+						   gimple_seq_last (seq)));
+	  t = gimple_assign_lhs (gimple_seq_last (seq));
+	  gimple_seq_set_location (seq, location);
+	  gsi_insert_seq_after (&gsi, seq, GSI_CONTINUE_LINKING);
+	  sz_arg = build_int_cst (pointer_sized_int_node, size_in_bytes);
+	}
     }
   else
     t = shadow;
@@ -1573,7 +1627,7 @@ build_check_stmt (location_t location, tree base, gimple_stmt_iterator *iter,
   /* Generate call to the run-time library (e.g. __asan_report_load8).  */
   gsi = gsi_start_bb (then_bb);
   g = gimple_build_call (report_error_func (is_store, size_in_bytes),
-			 1, base_addr);
+			 sz_arg ? 2 : 1, base_addr, sz_arg);
   gimple_set_location (g, location);
   gsi_insert_after (&gsi, g, GSI_NEW_STMT);
 
@@ -1621,7 +1675,8 @@ instrument_derefs (gimple_stmt_iterator *iter, tree t,
   int volatilep = 0, unsignedp = 0;
   tree inner = get_inner_reference (t, &bitsize, &bitpos, &offset,
 				    &mode, &unsignedp, &volatilep, false);
-  if (bitpos % (size_in_bytes * BITS_PER_UNIT)
+  if (((size_in_bytes & (size_in_bytes - 1)) == 0
+       && (bitpos % (size_in_bytes * BITS_PER_UNIT)))
       || bitsize != size_in_bytes * BITS_PER_UNIT)
     {
       if (TREE_CODE (t) == COMPONENT_REF
@@ -1634,6 +1689,8 @@ instrument_derefs (gimple_stmt_iterator *iter, tree t,
 	}
       return;
     }
+  if (bitpos % BITS_PER_UNIT)
+    return;
 
   if (TREE_CODE (inner) == VAR_DECL
       && offset == NULL_TREE
diff --git a/gcc/sanitizer.def b/gcc/sanitizer.def
index 015b1d8..0bb4682a 100644
--- a/gcc/sanitizer.def
+++ b/gcc/sanitizer.def
@@ -41,6 +41,9 @@ DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_REPORT_LOAD8, "__asan_report_load8",
 		      BT_FN_VOID_PTR, ATTR_TMPURE_NORETURN_NOTHROW_LEAF_LIST)
 DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_REPORT_LOAD16, "__asan_report_load16",
 		      BT_FN_VOID_PTR, ATTR_TMPURE_NORETURN_NOTHROW_LEAF_LIST)
+DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_REPORT_LOAD_N, "__asan_report_load_n",
+		      BT_FN_VOID_PTR_PTRMODE,
+		      ATTR_TMPURE_NORETURN_NOTHROW_LEAF_LIST)
 DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_REPORT_STORE1, "__asan_report_store1",
 		      BT_FN_VOID_PTR, ATTR_TMPURE_NORETURN_NOTHROW_LEAF_LIST)
 DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_REPORT_STORE2, "__asan_report_store2",
@@ -51,6 +54,9 @@ DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_REPORT_STORE8, "__asan_report_store8",
 		      BT_FN_VOID_PTR, ATTR_TMPURE_NORETURN_NOTHROW_LEAF_LIST)
 DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_REPORT_STORE16, "__asan_report_store16",
 		      BT_FN_VOID_PTR, ATTR_TMPURE_NORETURN_NOTHROW_LEAF_LIST)
+DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_REPORT_STORE_N, "__asan_report_store_n",
+		      BT_FN_VOID_PTR_PTRMODE,
+		      ATTR_TMPURE_NORETURN_NOTHROW_LEAF_LIST)
 DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_REGISTER_GLOBALS,
 		      "__asan_register_globals",
 		      BT_FN_VOID_PTR_PTRMODE, ATTR_NOTHROW_LEAF_LIST)

^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH 5/17] Fix bootstrap error
  2014-10-16  8:35 [PATCH 0/17] KASan 4.9 backport Yury Gribov
                   ` (4 preceding siblings ...)
  2014-10-16  8:38 ` [PATCH 6/17] Fix for PR 61530 Yury Gribov
@ 2014-10-16  8:38 ` Yury Gribov
  2014-10-16  8:47   ` Jakub Jelinek
  2014-10-16  8:39 ` [PATCH 7/17] Fix for PR 61547 Yury Gribov
                   ` (11 subsequent siblings)
  17 siblings, 1 reply; 49+ messages in thread
From: Yury Gribov @ 2014-10-16  8:38 UTC (permalink / raw)
  To: GCC Patches
  Cc: Jakub Jelinek, Dmitry Vyukov, Konstantin Khlebnikov,
	Andrey Ryabinin, Viacheslav Garbuzov

[-- Attachment #1: Type: text/plain, Size: 18 bytes --]

Same as mainline.

[-- Attachment #2: 0005-2014-10-15-Yury-Gribov-y.gribov-samsung.com.patch --]
[-- Type: text/x-patch, Size: 927 bytes --]

2014-10-15  Yury Gribov  <y.gribov@samsung.com>

	Backport from mainline
	2014-06-16  Yury Gribov  <y.gribov@samsung.com>

	* asan.c (build_check_stmt): Fix maybe-uninitialized warning.

diff --git a/gcc/asan.c b/gcc/asan.c
index 5c091d0..3729178 100644
--- a/gcc/asan.c
+++ b/gcc/asan.c
@@ -1635,6 +1635,13 @@ build_check_stmt (location_t location, tree base, tree len,
 
   gcc_assert (!(size_in_bytes > 0 && !non_zero_len_p));
 
+  if (start_instrumented && end_instrumented)
+    {
+      if (!before_p)
+        gsi_next (iter);
+      return;
+    }
+
   if (len)
     len = unshare_expr (len);
   else
@@ -1734,7 +1741,7 @@ build_check_stmt (location_t location, tree base, tree len,
   gsi_insert_after (&gsi, g, GSI_NEW_STMT);
   tree base_addr = gimple_assign_lhs (g);
 
-  tree t;
+  tree t = NULL_TREE;
   if (real_size_in_bytes >= 8)
     {
       tree shadow = build_shadow_mem_access (&gsi, location, base_addr,

^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH 6/17] Fix for PR 61530
  2014-10-16  8:35 [PATCH 0/17] KASan 4.9 backport Yury Gribov
                   ` (3 preceding siblings ...)
  2014-10-16  8:37 ` [PATCH 2/17] Introduction of __asan_loadN/__asan_storeN Yury Gribov
@ 2014-10-16  8:38 ` Yury Gribov
  2014-10-16  8:47   ` Jakub Jelinek
  2014-10-16  8:38 ` [PATCH 5/17] Fix bootstrap error Yury Gribov
                   ` (12 subsequent siblings)
  17 siblings, 1 reply; 49+ messages in thread
From: Yury Gribov @ 2014-10-16  8:38 UTC (permalink / raw)
  To: GCC Patches
  Cc: Jakub Jelinek, Dmitry Vyukov, Konstantin Khlebnikov,
	Andrey Ryabinin, Viacheslav Garbuzov

[-- Attachment #1: Type: text/plain, Size: 18 bytes --]

Same as mainline.

[-- Attachment #2: 0006-2014-10-15-Yury-Gribov-y.gribov-samsung.com.patch --]
[-- Type: text/x-patch, Size: 1174 bytes --]

2014-10-15  Yury Gribov  <y.gribov@samsung.com>

	Backport from mainline
	2014-06-18  Yury Gribov  <y.gribov@samsung.com>

	PR sanitizer/61530

	* asan.c (build_check_stmt): Add condition.

	* c-c++-common/asan/pr61530.c: New test.

diff --git a/gcc/asan.c b/gcc/asan.c
index 3729178..c838423 100644
--- a/gcc/asan.c
+++ b/gcc/asan.c
@@ -1653,6 +1653,7 @@ build_check_stmt (location_t location, tree base, tree len,
   if (size_in_bytes > 1)
     {
       if ((size_in_bytes & (size_in_bytes - 1)) != 0
+	  || !is_scalar_access
 	  || size_in_bytes > 16)
 	size_in_bytes = -1;
       else if (align && align < size_in_bytes * BITS_PER_UNIT)
diff --git a/gcc/testsuite/c-c++-common/asan/pr61530.c b/gcc/testsuite/c-c++-common/asan/pr61530.c
new file mode 100644
index 0000000..e306a71
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/asan/pr61530.c
@@ -0,0 +1,17 @@
+/* { dg-do run } */
+/* { dg-shouldfail "asan" } */
+
+__attribute__((noinline,noclone)) void
+foo (char *a, char *b) {
+  a[0] = b[0] = 0;
+  __builtin_memcpy(a, b, 4);
+}
+
+int
+main () {
+  char a, b;
+  foo (&a, &b);
+  return 0;
+}
+
+/* { dg-output "ERROR: AddressSanitizer: stack-buffer-overflow" } */

^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH 7/17] Fix for PR 61547
  2014-10-16  8:35 [PATCH 0/17] KASan 4.9 backport Yury Gribov
                   ` (5 preceding siblings ...)
  2014-10-16  8:38 ` [PATCH 5/17] Fix bootstrap error Yury Gribov
@ 2014-10-16  8:39 ` Yury Gribov
  2014-10-16  8:49   ` Jakub Jelinek
  2014-10-16  8:39 ` [PATCH 8/17] Optimization of strlen instrumentation Yury Gribov
                   ` (10 subsequent siblings)
  17 siblings, 1 reply; 49+ messages in thread
From: Yury Gribov @ 2014-10-16  8:39 UTC (permalink / raw)
  To: GCC Patches
  Cc: Jakub Jelinek, Dmitry Vyukov, Konstantin Khlebnikov,
	Andrey Ryabinin, Viacheslav Garbuzov

[-- Attachment #1: Type: text/plain, Size: 109 bytes --]

Difference from mainline: replaced non-C-friendly bool with unsigned 
char (see patch 0001 for explanation).

[-- Attachment #2: 0007-2014-10-15-Yury-Gribov-y.gribov-samsung.com.patch --]
[-- Type: text/x-patch, Size: 2575 bytes --]

2014-10-15  Yury Gribov  <y.gribov@samsung.com>

	Backport from mainline
	2014-06-18  Yury Gribov  <y.gribov@samsung.com>

	PR sanitizer/61547

	* asan.c (instrument_strlen_call): Fixed instrumentation of
	trailing byte.

	* c-c++-common/asan/strlen-overflow-1.c: New test.

diff --git a/gcc/asan.c b/gcc/asan.c
index c838423..06177ac 100644
--- a/gcc/asan.c
+++ b/gcc/asan.c
@@ -2037,19 +2037,19 @@ instrument_strlen_call (gimple_stmt_iterator *iter)
 
   build_check_stmt (loc, gimple_assign_lhs (str_arg_ssa), NULL_TREE, 1, iter,
 		    /*non_zero_len_p*/true, /*before_p=*/true,
-		    /*is_store=*/false, /*is_scalar_access*/false, /*align*/0);
+		    /*is_store=*/false, /*is_scalar_access*/true, /*align*/0);
 
-  gimple stmt =
-    gimple_build_assign_with_ops (PLUS_EXPR,
-				  make_ssa_name (TREE_TYPE (len), NULL),
-				  len,
-				  build_int_cst (TREE_TYPE (len), 1));
-  gimple_set_location (stmt, loc);
-  gsi_insert_after (iter, stmt, GSI_NEW_STMT);
+  gimple g =
+    gimple_build_assign_with_ops (POINTER_PLUS_EXPR,
+				  make_ssa_name (cptr_type, NULL),
+				  gimple_assign_lhs (str_arg_ssa),
+				  len);
+  gimple_set_location (g, loc);
+  gsi_insert_after (iter, g, GSI_NEW_STMT);
 
-  build_check_stmt (loc, gimple_assign_lhs (stmt), len, 1, iter,
+  build_check_stmt (loc, gimple_assign_lhs (g), NULL_TREE, 1, iter,
 		    /*non_zero_len_p*/true, /*before_p=*/false,
-		    /*is_store=*/false, /*is_scalar_access*/false, /*align*/0);
+		    /*is_store=*/false, /*is_scalar_access*/true, /*align*/0);
 
   return true;
 }
diff --git a/gcc/testsuite/c-c++-common/asan/strlen-overflow-1.c b/gcc/testsuite/c-c++-common/asan/strlen-overflow-1.c
new file mode 100644
index 0000000..426c8fe
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/asan/strlen-overflow-1.c
@@ -0,0 +1,33 @@
+/* { dg-do run } */
+/* { dg-skip-if "" { *-*-* } { "-flto" } { "" } } */
+/* { dg-shouldfail "asan" } */
+
+#ifndef __cplusplus
+#define bool unsigned char
+#endif
+
+#include <sanitizer/asan_interface.h>
+
+char a[2] = "0";
+
+#ifdef __cplusplus
+extern "C"
+#endif
+
+__attribute__((no_sanitize_address, noinline)) __SIZE_TYPE__
+strlen (const char *p) {
+
+  __SIZE_TYPE__ n = 0;
+  for (; *p; ++n, ++p);
+  return n;
+}
+
+int main () {
+  char *p = &a[0];
+  asm ("" : "+r"(p));
+  __asan_poison_memory_region ((char *)&a[1], 1);
+  return __builtin_strlen (a);
+}
+
+/* { dg-output "READ of size 1 at 0x\[0-9a-f\]+ thread T0.*(\n|\r\n|\r)" } */
+/* { dg-output "    #0 0x\[0-9a-f\]+ (in _*main (\[^\n\r]*strlen-overflow-1.c:29|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } */

^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH 8/17] Optimization of strlen instrumentation
  2014-10-16  8:35 [PATCH 0/17] KASan 4.9 backport Yury Gribov
                   ` (6 preceding siblings ...)
  2014-10-16  8:39 ` [PATCH 7/17] Fix for PR 61547 Yury Gribov
@ 2014-10-16  8:39 ` Yury Gribov
  2014-10-16  8:50   ` Jakub Jelinek
  2014-10-16  8:40 ` [PATCH 9/17] Initial KAsan support Yury Gribov
                   ` (9 subsequent siblings)
  17 siblings, 1 reply; 49+ messages in thread
From: Yury Gribov @ 2014-10-16  8:39 UTC (permalink / raw)
  To: GCC Patches
  Cc: Jakub Jelinek, Dmitry Vyukov, Konstantin Khlebnikov,
	Andrey Ryabinin, Viacheslav Garbuzov

[-- Attachment #1: Type: text/plain, Size: 109 bytes --]

Difference from mainline: replaced non-C-friendly bool with unsigned 
char (see patch 0001 for explanation).

[-- Attachment #2: 0008-Do-not-instrument-first-byte-in-strlen-if-already-in.patch --]
[-- Type: text/x-patch, Size: 1869 bytes --]

Do not instrument first byte in strlen if already instrumented.

2014-10-15  Yury Gribov  <y.gribov@samsung.com>

	Backport from mainline
	2014-06-24  Max Ostapenko  <m.ostapenko@partner.samsung.com>

	* asan.c (instrument_strlen_call): Do not instrument first byte in strlen
	if already instrumented.

	* c-c++-common/asan/no-redundant-instrumentation-9.c: New test.

diff --git a/gcc/asan.c b/gcc/asan.c
index 06177ac..0789ad3 100644
--- a/gcc/asan.c
+++ b/gcc/asan.c
@@ -2026,6 +2026,7 @@ instrument_strlen_call (gimple_stmt_iterator *iter)
 
   location_t loc = gimple_location (call);
   tree str_arg = gimple_call_arg (call, 0);
+  bool start_instrumented = has_mem_ref_been_instrumented (str_arg, 1);
 
   tree cptr_type = build_pointer_type (char_type_node);
   gimple str_arg_ssa =
@@ -2037,7 +2038,8 @@ instrument_strlen_call (gimple_stmt_iterator *iter)
 
   build_check_stmt (loc, gimple_assign_lhs (str_arg_ssa), NULL_TREE, 1, iter,
 		    /*non_zero_len_p*/true, /*before_p=*/true,
-		    /*is_store=*/false, /*is_scalar_access*/true, /*align*/0);
+		    /*is_store=*/false, /*is_scalar_access*/true, /*align*/0,
+		    start_instrumented, start_instrumented);
 
   gimple g =
     gimple_build_assign_with_ops (POINTER_PLUS_EXPR,
diff --git a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-9.c b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-9.c
new file mode 100644
index 0000000..c6575ad
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-9.c
@@ -0,0 +1,13 @@
+/* { dg-options "-fdump-tree-asan0" } */
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "*" } { "-O0" } } */
+
+__SIZE_TYPE__
+f (char *a)
+{
+  a[0] = '1';
+  return  __builtin_strlen (a);
+}
+
+/* { dg-final { scan-tree-dump-times "__asan_report_load1" 1 "asan0" } } */
+/* { dg-final { cleanup-tree-dump "asan0" } } */

^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH 9/17] Initial KAsan support
  2014-10-16  8:35 [PATCH 0/17] KASan 4.9 backport Yury Gribov
                   ` (7 preceding siblings ...)
  2014-10-16  8:39 ` [PATCH 8/17] Optimization of strlen instrumentation Yury Gribov
@ 2014-10-16  8:40 ` Yury Gribov
  2014-10-16  8:51   ` Jakub Jelinek
  2014-10-17  7:29   ` Eric Botcazou
  2014-10-16  8:40 ` [PATCH 10/17] Support fnspec for internal fns Yury Gribov
                   ` (8 subsequent siblings)
  17 siblings, 2 replies; 49+ messages in thread
From: Yury Gribov @ 2014-10-16  8:40 UTC (permalink / raw)
  To: GCC Patches
  Cc: Jakub Jelinek, Dmitry Vyukov, Konstantin Khlebnikov,
	Andrey Ryabinin, Viacheslav Garbuzov

[-- Attachment #1: Type: text/plain, Size: 130 bytes --]

The patch was slightly updated to take care of missing UBSan work 
(SANITIZE_FLOAT_DIVIDE, SANITIZE_FLOAT_CAST, SANITIZE_BOUNDS).

[-- Attachment #2: 0009-2014-10-15-Yury-Gribov-y.gribov-samsung.com.patch --]
[-- Type: text/x-patch, Size: 7411 bytes --]

2014-10-15  Yury Gribov  <y.gribov@samsung.com>

	Backport from mainline
	2014-07-31  Yury Gribov  <y.gribov@samsung.com>

	* doc/cpp.texi (__SANITIZE_ADDRESS__): Updated description.
	* doc/invoke.texi (-fsanitize=kernel-address): Describe new option.
	* flag-types.h (SANITIZE_USER_ADDRESS, SANITIZE_KERNEL_ADDRESS):
	New enums.
	* gcc.c (sanitize_spec_function): Support new option.
	(SANITIZER_SPEC): Remove now redundant check.
	* opts.c (common_handle_option): Support new option.
	(finish_options): Check for incompatibilities.
	* toplev.c (process_options): Split userspace-specific checks.

diff --git a/gcc/doc/cpp.texi b/gcc/doc/cpp.texi
index aaed739..0a6e50c 100644
--- a/gcc/doc/cpp.texi
+++ b/gcc/doc/cpp.texi
@@ -2354,8 +2354,8 @@ This macro is defined, with value 3, when @option{-fstack-protector-strong} is
 in use.
 
 @item __SANITIZE_ADDRESS__
-This macro is defined, with value 1, when @option{-fsanitize=address} is
-in use.
+This macro is defined, with value 1, when @option{-fsanitize=address}
+or @option{-fsanitize=kernel-address} are in use.
 
 @item __TIMESTAMP__
 This macro expands to a string constant that describes the date and time
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 4012f08..179f273 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -5286,6 +5286,11 @@ more details.  The run-time behavior can be influenced using the
 @url{https://code.google.com/p/address-sanitizer/wiki/Flags#Run-time_flags} for
 a list of supported options.
 
+@item -fsanitize=kernel-address
+@opindex fsanitize=kernel-address
+Enable AddressSanitizer for Linux kernel.
+See @uref{http://code.google.com/p/address-sanitizer/wiki/AddressSanitizerForKernel} for more details.
+
 @item -fsanitize=thread
 @opindex fsanitize=thread
 Enable ThreadSanitizer, a fast data race detector.
diff --git a/gcc/flag-types.h b/gcc/flag-types.h
index ec16faa..1dd1b3e 100644
--- a/gcc/flag-types.h
+++ b/gcc/flag-types.h
@@ -204,20 +204,22 @@ enum vect_cost_model {
 enum sanitize_code {
   /* AddressSanitizer.  */
   SANITIZE_ADDRESS = 1 << 0,
+  SANITIZE_USER_ADDRESS = 1 << 1,
+  SANITIZE_KERNEL_ADDRESS = 1 << 2,
   /* ThreadSanitizer.  */
-  SANITIZE_THREAD = 1 << 1,
+  SANITIZE_THREAD = 1 << 3,
   /* LeakSanitizer.  */
-  SANITIZE_LEAK = 1 << 2,
+  SANITIZE_LEAK = 1 << 4,
   /* UndefinedBehaviorSanitizer.  */
-  SANITIZE_SHIFT = 1 << 3,
-  SANITIZE_DIVIDE = 1 << 4,
-  SANITIZE_UNREACHABLE = 1 << 5,
-  SANITIZE_VLA = 1 << 6,
-  SANITIZE_NULL = 1 << 7,
-  SANITIZE_RETURN = 1 << 8,
-  SANITIZE_SI_OVERFLOW = 1 << 9,
-  SANITIZE_BOOL = 1 << 10,
-  SANITIZE_ENUM = 1 << 11,
+  SANITIZE_SHIFT = 1 << 5,
+  SANITIZE_DIVIDE = 1 << 6,
+  SANITIZE_UNREACHABLE = 1 << 7,
+  SANITIZE_VLA = 1 << 8,
+  SANITIZE_NULL = 1 << 9,
+  SANITIZE_RETURN = 1 << 10,
+  SANITIZE_SI_OVERFLOW = 1 << 11,
+  SANITIZE_BOOL = 1 << 12,
+  SANITIZE_ENUM = 1 << 13,
   SANITIZE_UNDEFINED = SANITIZE_SHIFT | SANITIZE_DIVIDE | SANITIZE_UNREACHABLE
 		       | SANITIZE_VLA | SANITIZE_NULL | SANITIZE_RETURN
 		       | SANITIZE_SI_OVERFLOW | SANITIZE_BOOL | SANITIZE_ENUM
diff --git a/gcc/gcc.c b/gcc/gcc.c
index 9c4c40c..1034de8 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -734,8 +734,7 @@ proper position among the other output files.  */
 #ifndef SANITIZER_SPEC
 #define SANITIZER_SPEC "\
 %{!nostdlib:%{!nodefaultlibs:%{%:sanitize(address):" LIBASAN_SPEC "\
-    %{static:%ecannot specify -static with -fsanitize=address}\
-    %{%:sanitize(thread):%e-fsanitize=address is incompatible with -fsanitize=thread}}\
+    %{static:%ecannot specify -static with -fsanitize=address}}\
     %{%:sanitize(thread):" LIBTSAN_SPEC "\
     %{!pie:%{!shared:%e-fsanitize=thread linking must be done with -pie or -shared}}}\
     %{%:sanitize(undefined):" LIBUBSAN_SPEC "}\
@@ -8173,7 +8172,9 @@ sanitize_spec_function (int argc, const char **argv)
     return NULL;
 
   if (strcmp (argv[0], "address") == 0)
-    return (flag_sanitize & SANITIZE_ADDRESS) ? "" : NULL;
+    return (flag_sanitize & SANITIZE_USER_ADDRESS) ? "" : NULL;
+  if (strcmp (argv[0], "kernel-address") == 0)
+    return (flag_sanitize & SANITIZE_KERNEL_ADDRESS) ? "" : NULL;
   if (strcmp (argv[0], "thread") == 0)
     return (flag_sanitize & SANITIZE_THREAD) ? "" : NULL;
   if (strcmp (argv[0], "undefined") == 0)
diff --git a/gcc/opts.c b/gcc/opts.c
index bbd6b9c..fbdebd7 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -868,6 +868,20 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set,
   /* The -gsplit-dwarf option requires -gpubnames.  */
   if (opts->x_dwarf_split_debug_info)
     opts->x_debug_generate_pub_sections = 1;
+
+  /* Userspace and kernel ASan conflict with each other and with TSan.  */
+
+  if ((flag_sanitize & SANITIZE_USER_ADDRESS)
+      && (flag_sanitize & SANITIZE_KERNEL_ADDRESS))
+    error_at (loc,
+              "-fsanitize=address is incompatible with "
+              "-fsanitize=kernel-address");
+
+  if ((flag_sanitize & SANITIZE_ADDRESS)
+      && (flag_sanitize & SANITIZE_THREAD))
+    error_at (loc,
+              "-fsanitize=address and -fsanitize=kernel-address "
+              "are incompatible with -fsanitize=thread");
 }
 
 #define LEFT_COLUMN	27
@@ -1453,7 +1467,10 @@ common_handle_option (struct gcc_options *opts,
 	      size_t len;
 	    } spec[] =
 	    {
-	      { "address", SANITIZE_ADDRESS, sizeof "address" - 1 },
+	      { "address", SANITIZE_ADDRESS | SANITIZE_USER_ADDRESS,
+		sizeof "address" - 1 },
+	      { "kernel-address", SANITIZE_ADDRESS | SANITIZE_KERNEL_ADDRESS,
+		sizeof "kernel-address" - 1 },
 	      { "thread", SANITIZE_THREAD, sizeof "thread" - 1 },
 	      { "leak", SANITIZE_LEAK, sizeof "leak" - 1 },
 	      { "shift", SANITIZE_SHIFT, sizeof "shift" - 1 },
@@ -1514,6 +1531,25 @@ common_handle_option (struct gcc_options *opts,
 	   the null pointer checks.  */
 	if (flag_sanitize & SANITIZE_NULL)
 	  opts->x_flag_delete_null_pointer_checks = 0;
+
+	/* Kernel ASan implies normal ASan but does not yet support
+	   all features.  */
+	if (flag_sanitize & SANITIZE_KERNEL_ADDRESS)
+	  {
+	    maybe_set_param_value (PARAM_ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD, 0,
+				   opts->x_param_values,
+				   opts_set->x_param_values);
+	    maybe_set_param_value (PARAM_ASAN_GLOBALS, 0,
+				   opts->x_param_values,
+				   opts_set->x_param_values);
+	    maybe_set_param_value (PARAM_ASAN_STACK, 0,
+				   opts->x_param_values,
+				   opts_set->x_param_values);
+	    maybe_set_param_value (PARAM_ASAN_USE_AFTER_RETURN, 0,
+				   opts->x_param_values,
+				   opts_set->x_param_values);
+	  }
+
 	break;
       }
 
diff --git a/gcc/toplev.c b/gcc/toplev.c
index d646faf..588fa2b 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -1555,9 +1555,18 @@ process_options (void)
     warn_stack_protect = 0;
 
   /* Address Sanitizer needs porting to each target architecture.  */
+
   if ((flag_sanitize & SANITIZE_ADDRESS)
-      && (targetm.asan_shadow_offset == NULL
-	  || !FRAME_GROWS_DOWNWARD))
+      && !FRAME_GROWS_DOWNWARD)
+    {
+      warning (0,
+	       "-fsanitize=address and -fsanitize=kernel-address "
+	       "are not supported for this target");
+      flag_sanitize &= ~SANITIZE_ADDRESS;
+    }
+
+  if ((flag_sanitize & SANITIZE_USER_ADDRESS)
+      && targetm.asan_shadow_offset == NULL)
     {
       warning (0, "-fsanitize=address not supported for this target");
       flag_sanitize &= ~SANITIZE_ADDRESS;

^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH 10/17] Support fnspec for internal fns
  2014-10-16  8:35 [PATCH 0/17] KASan 4.9 backport Yury Gribov
                   ` (8 preceding siblings ...)
  2014-10-16  8:40 ` [PATCH 9/17] Initial KAsan support Yury Gribov
@ 2014-10-16  8:40 ` Yury Gribov
  2014-10-16  8:52   ` Jakub Jelinek
  2014-10-16  8:41 ` [PATCH 13/17] Fix for PR 62089 Yury Gribov
                   ` (7 subsequent siblings)
  17 siblings, 1 reply; 49+ messages in thread
From: Yury Gribov @ 2014-10-16  8:40 UTC (permalink / raw)
  To: GCC Patches
  Cc: Jakub Jelinek, Dmitry Vyukov, Konstantin Khlebnikov,
	Andrey Ryabinin, Viacheslav Garbuzov

[-- Attachment #1: Type: text/plain, Size: 83 bytes --]

The patch was slightly updated to take care of missing UBSan work 
(UBSAN_BOUNDS).

[-- Attachment #2: 0010-Added-fnspec-to-internal-functions.patch --]
[-- Type: text/x-patch, Size: 8656 bytes --]

Added fnspec to internal functions.

2014-10-15  Yury Gribov  <y.gribov@samsung.com>

	Backport from mainline
	2014-08-11  Yury Gribov  <y.gribov@samsung.com>

        * gimple.c (gimple_call_fnspec): Support internal functions.
        (gimple_call_return_flags): Use const.
        * Makefile.in (GTFILES): Add internal-fn.h to list of GC files.
        * internal-fn.def: Add fnspec information.
        * internal-fn.h (internal_fn_fnspec): New function.
        (init_internal_fns): Declare new function.
        * internal-fn.c (internal_fn_fnspec_array): New global variable.
        (init_internal_fns): New function.
        * tree-core.h: Update macro call.
        * tree.c (build_common_builtin_nodes): Initialize internal fns.

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 5dd1c25..b47733c 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -2282,7 +2282,9 @@ GTFILES = $(CPP_ID_DATA_H) $(srcdir)/input.h $(srcdir)/coretypes.h \
   $(srcdir)/vtable-verify.c \
   $(srcdir)/asan.c \
   $(srcdir)/ubsan.c \
-  $(srcdir)/tsan.c $(srcdir)/ipa-devirt.c \
+  $(srcdir)/tsan.c \
+  $(srcdir)/ipa-devirt.c \
+  $(srcdir)/internal-fn.h \
   @all_gtfiles@
 
 # Compute the list of GT header files from the corresponding C sources,
diff --git a/gcc/gimple.c b/gcc/gimple.c
index 2a278e4..30d1653 100644
--- a/gcc/gimple.c
+++ b/gcc/gimple.c
@@ -1329,11 +1329,14 @@ gimple_call_flags (const_gimple stmt)
 
 /* Return the "fn spec" string for call STMT.  */
 
-static tree
+static const_tree
 gimple_call_fnspec (const_gimple stmt)
 {
   tree type, attr;
 
+  if (gimple_call_internal_p (stmt))
+    return internal_fn_fnspec (gimple_call_internal_fn (stmt));
+
   type = gimple_call_fntype (stmt);
   if (!type)
     return NULL_TREE;
@@ -1350,7 +1353,7 @@ gimple_call_fnspec (const_gimple stmt)
 int
 gimple_call_arg_flags (const_gimple stmt, unsigned arg)
 {
-  tree attr = gimple_call_fnspec (stmt);
+  const_tree attr = gimple_call_fnspec (stmt);
 
   if (!attr || 1 + arg >= (unsigned) TREE_STRING_LENGTH (attr))
     return 0;
@@ -1384,7 +1387,7 @@ gimple_call_arg_flags (const_gimple stmt, unsigned arg)
 int
 gimple_call_return_flags (const_gimple stmt)
 {
-  tree attr;
+  const_tree attr;
 
   if (gimple_call_flags (stmt) & ECF_MALLOC)
     return ERF_NOALIAS;
diff --git a/gcc/internal-fn.c b/gcc/internal-fn.c
index 1062ea8..5b881f1 100644
--- a/gcc/internal-fn.c
+++ b/gcc/internal-fn.c
@@ -40,7 +40,7 @@ along with GCC; see the file COPYING3.  If not see
 
 /* The names of each internal function, indexed by function number.  */
 const char *const internal_fn_name_array[] = {
-#define DEF_INTERNAL_FN(CODE, FLAGS) #CODE,
+#define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) #CODE,
 #include "internal-fn.def"
 #undef DEF_INTERNAL_FN
   "<invalid-fn>"
@@ -48,12 +48,26 @@ const char *const internal_fn_name_array[] = {
 
 /* The ECF_* flags of each internal function, indexed by function number.  */
 const int internal_fn_flags_array[] = {
-#define DEF_INTERNAL_FN(CODE, FLAGS) FLAGS,
+#define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) FLAGS,
 #include "internal-fn.def"
 #undef DEF_INTERNAL_FN
   0
 };
 
+/* Fnspec of each internal function, indexed by function number.  */
+const_tree internal_fn_fnspec_array[IFN_LAST + 1];
+
+void
+init_internal_fns ()
+{
+#define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
+  if (FNSPEC) internal_fn_fnspec_array[IFN_##CODE] = \
+    build_string ((int) sizeof (FNSPEC) + 1, FNSPEC ? FNSPEC : "");
+#include "internal-fn.def"
+#undef DEF_INTERNAL_FN
+  internal_fn_fnspec_array[IFN_LAST] = 0;
+}
+
 /* ARRAY_TYPE is an array of vector modes.  Return the associated insn
    for load-lanes-style optab OPTAB.  The insn must exist.  */
 
@@ -891,7 +905,7 @@ expand_BUILTIN_EXPECT (gimple stmt)
 
    where STMT is the statement that performs the call. */
 static void (*const internal_fn_expanders[]) (gimple) = {
-#define DEF_INTERNAL_FN(CODE, FLAGS) expand_##CODE,
+#define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) expand_##CODE,
 #include "internal-fn.def"
 #undef DEF_INTERNAL_FN
   0
diff --git a/gcc/internal-fn.def b/gcc/internal-fn.def
index 31dc4c9..f60a9b0 100644
--- a/gcc/internal-fn.def
+++ b/gcc/internal-fn.def
@@ -28,28 +28,29 @@ along with GCC; see the file COPYING3.  If not see
 
    Each entry in this file has the form:
 
-     DEF_INTERNAL_FN (NAME, FLAGS)
+     DEF_INTERNAL_FN (NAME, FLAGS, FNSPEC)
 
-   where NAME is the name of the function and FLAGS is a set of
-   ECF_* flags.  Each entry must have a corresponding expander
-   of the form:
+   where NAME is the name of the function, FLAGS is a set of
+   ECF_* flags and FNSPEC is a string describing functions fnspec.
+   
+   Each entry must have a corresponding expander of the form:
 
      void expand_NAME (gimple stmt)
 
    where STMT is the statement that performs the call.  */
 
-DEF_INTERNAL_FN (LOAD_LANES, ECF_CONST | ECF_LEAF)
-DEF_INTERNAL_FN (STORE_LANES, ECF_CONST | ECF_LEAF)
-DEF_INTERNAL_FN (GOMP_SIMD_LANE, ECF_NOVOPS | ECF_LEAF | ECF_NOTHROW)
-DEF_INTERNAL_FN (GOMP_SIMD_VF, ECF_CONST | ECF_LEAF | ECF_NOTHROW)
-DEF_INTERNAL_FN (GOMP_SIMD_LAST_LANE, ECF_CONST | ECF_LEAF | ECF_NOTHROW)
-DEF_INTERNAL_FN (LOOP_VECTORIZED, ECF_NOVOPS | ECF_LEAF | ECF_NOTHROW)
-DEF_INTERNAL_FN (MASK_LOAD, ECF_PURE | ECF_LEAF)
-DEF_INTERNAL_FN (MASK_STORE, ECF_LEAF)
-DEF_INTERNAL_FN (ANNOTATE,  ECF_CONST | ECF_LEAF | ECF_NOTHROW)
-DEF_INTERNAL_FN (UBSAN_NULL, ECF_LEAF | ECF_NOTHROW)
-DEF_INTERNAL_FN (UBSAN_CHECK_ADD, ECF_CONST | ECF_LEAF | ECF_NOTHROW)
-DEF_INTERNAL_FN (UBSAN_CHECK_SUB, ECF_CONST | ECF_LEAF | ECF_NOTHROW)
-DEF_INTERNAL_FN (UBSAN_CHECK_MUL, ECF_CONST | ECF_LEAF | ECF_NOTHROW)
-DEF_INTERNAL_FN (ABNORMAL_DISPATCHER, ECF_NORETURN)
-DEF_INTERNAL_FN (BUILTIN_EXPECT, ECF_CONST | ECF_LEAF | ECF_NOTHROW)
+DEF_INTERNAL_FN (LOAD_LANES, ECF_CONST | ECF_LEAF, NULL)
+DEF_INTERNAL_FN (STORE_LANES, ECF_CONST | ECF_LEAF, NULL)
+DEF_INTERNAL_FN (GOMP_SIMD_LANE, ECF_NOVOPS | ECF_LEAF | ECF_NOTHROW, NULL)
+DEF_INTERNAL_FN (GOMP_SIMD_VF, ECF_CONST | ECF_LEAF | ECF_NOTHROW, NULL)
+DEF_INTERNAL_FN (GOMP_SIMD_LAST_LANE, ECF_CONST | ECF_LEAF | ECF_NOTHROW, NULL)
+DEF_INTERNAL_FN (LOOP_VECTORIZED, ECF_NOVOPS | ECF_LEAF | ECF_NOTHROW, NULL)
+DEF_INTERNAL_FN (MASK_LOAD, ECF_PURE | ECF_LEAF, NULL)
+DEF_INTERNAL_FN (MASK_STORE, ECF_LEAF, NULL)
+DEF_INTERNAL_FN (ANNOTATE,  ECF_CONST | ECF_LEAF | ECF_NOTHROW, NULL)
+DEF_INTERNAL_FN (UBSAN_NULL, ECF_LEAF | ECF_NOTHROW, ".W.")
+DEF_INTERNAL_FN (UBSAN_CHECK_ADD, ECF_CONST | ECF_LEAF | ECF_NOTHROW, NULL)
+DEF_INTERNAL_FN (UBSAN_CHECK_SUB, ECF_CONST | ECF_LEAF | ECF_NOTHROW, NULL)
+DEF_INTERNAL_FN (UBSAN_CHECK_MUL, ECF_CONST | ECF_LEAF | ECF_NOTHROW, NULL)
+DEF_INTERNAL_FN (ABNORMAL_DISPATCHER, ECF_NORETURN, NULL)
+DEF_INTERNAL_FN (BUILTIN_EXPECT, ECF_CONST | ECF_LEAF | ECF_NOTHROW, NULL)
diff --git a/gcc/internal-fn.h b/gcc/internal-fn.h
index 9c3215f..af93e15 100644
--- a/gcc/internal-fn.h
+++ b/gcc/internal-fn.h
@@ -21,12 +21,16 @@ along with GCC; see the file COPYING3.  If not see
 #define GCC_INTERNAL_FN_H
 
 enum internal_fn {
-#define DEF_INTERNAL_FN(CODE, FLAGS) IFN_##CODE,
+#define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) IFN_##CODE,
 #include "internal-fn.def"
 #undef DEF_INTERNAL_FN
   IFN_LAST
 };
 
+/* Initialize internal function tables.  */
+
+extern void init_internal_fns ();
+
 /* Return the name of internal function FN.  The name is only meaningful
    for dumps; it has no linkage.  */
 
@@ -48,6 +52,16 @@ internal_fn_flags (enum internal_fn fn)
   return internal_fn_flags_array[(int) fn];
 }
 
+/* Return fnspec for function FN.  */
+
+extern GTY(()) const_tree internal_fn_fnspec_array[IFN_LAST + 1];
+
+static inline const_tree
+internal_fn_fnspec (enum internal_fn fn)
+{
+  return internal_fn_fnspec_array[(int) fn];
+}
+
 extern void expand_internal_call (gimple);
 
 #endif
diff --git a/gcc/tree.c b/gcc/tree.c
index 069abb7..77e9631 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -9875,8 +9875,9 @@ local_define_builtin (const char *name, tree type, enum built_in_function code,
 }
 
 /* Call this function after instantiating all builtins that the language
-   front end cares about.  This will build the rest of the builtins that
-   are relied upon by the tree optimizers and the middle-end.  */
+   front end cares about.  This will build the rest of the builtins
+   and internal function that are relied upon by the tree optimizers and
+   the middle-end.  */
 
 void
 build_common_builtin_nodes (void)
@@ -10109,6 +10110,8 @@ build_common_builtin_nodes (void)
 			      ECF_CONST | ECF_NOTHROW | ECF_LEAF);
       }
   }
+
+  init_internal_fns ();
 }
 
 /* HACK.  GROSS.  This is absolutely disgusting.  I wish there was a

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 1/17] Install asan_interface.h
  2014-10-16  8:36 ` [PATCH 1/17] Install asan_interface.h Yury Gribov
@ 2014-10-16  8:41   ` Jakub Jelinek
  0 siblings, 0 replies; 49+ messages in thread
From: Jakub Jelinek @ 2014-10-16  8:41 UTC (permalink / raw)
  To: Yury Gribov
  Cc: GCC Patches, Dmitry Vyukov, Konstantin Khlebnikov,
	Andrey Ryabinin, Viacheslav Garbuzov

On Thu, Oct 16, 2014 at 12:35:51PM +0400, Yury Gribov wrote:
> 2014-10-15  Yury Gribov  <y.gribov@samsung.com>
> 
> 	Backport from mainline
> 	2014-05-14  Yury Gribov  <y.gribov@samsung.com>
> 
> 	PR sanitizer/61100
> 
> 	* Makefile.am (nodist_saninclude_HEADERS): Install
> 	public headers.
> 	* Makefile.in: Regenerate.
> 
> 	* c-c++-common/asan/asan-interface-1.c: New test.
> 	* lib/asan-dg.exp (asan_include_flags): New function.
> 	(asan_init): Call asan_include_flags to obtain path
> 	to sanitizer headers.
> 
> --- /dev/null
> +++ b/gcc/testsuite/c-c++-common/asan/asan-interface-1.c
> @@ -0,0 +1,17 @@
> +/* Check that interface headers work. */
> +
> +/* { dg-do run { target { *-*-linux* } } } */
> +
> +#ifndef __cplusplus
> +#define bool unsigned char
> +#endif
> +

Please #include <stdbool.h>
instead.

> +#include <sanitizer/asan_interface.h>
> +
> +int main() {
> +  char tmp;
> +  if (__asan_address_is_poisoned((volatile char *)&tmp + 1))
> +    return 0;
> +  return 1;
> +}
> +

Ok with that change, but please wait for the whole series to be approved
(applies to all patches fromthe series).

	Jakub

^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH 11/17] Move Asan instrumentation to sanopt pass
  2014-10-16  8:35 [PATCH 0/17] KASan 4.9 backport Yury Gribov
                   ` (10 preceding siblings ...)
  2014-10-16  8:41 ` [PATCH 13/17] Fix for PR 62089 Yury Gribov
@ 2014-10-16  8:41 ` Yury Gribov
  2014-10-16  8:52   ` Jakub Jelinek
  2014-10-16  8:41 ` [PATCH 12/17] Fix off-by-one Yury Gribov
                   ` (5 subsequent siblings)
  17 siblings, 1 reply; 49+ messages in thread
From: Yury Gribov @ 2014-10-16  8:41 UTC (permalink / raw)
  To: GCC Patches
  Cc: Jakub Jelinek, Dmitry Vyukov, Konstantin Khlebnikov,
	Andrey Ryabinin, Viacheslav Garbuzov

[-- Attachment #1: Type: text/plain, Size: 83 bytes --]

The patch was slightly updated to take care of missing UBSan work 
(UBSAN_BOUNDS).

[-- Attachment #2: 0011-Move-inlining-of-Asan-memory-checks-to-sanopt-pass.patch --]
[-- Type: text/x-patch, Size: 42158 bytes --]

Move inlining of Asan memory checks to sanopt pass.
Change asan-instrumentation-with-call-threshold to more closely match LLVM.

2014-10-15  Yury Gribov  <y.gribov@samsung.com>

	Backport from mainline
	2014-08-11  Yury Gribov  <y.gribov@samsung.com>

	* asan.c (asan_check_flags): New enum.
	(build_check_stmt_with_calls): Removed function.
	(build_check_stmt): Split inlining logic to
	asan_expand_check_ifn.
	(instrument_derefs): Rename parameter.
	(instrument_mem_region_access): Rename parameter.
	(instrument_strlen_call): Likewise.
	(asan_expand_check_ifn): New function.
	(asan_instrument): Remove old code.
	(pass_sanopt::execute): Change handling of
	asan-instrumentation-with-call-threshold.
	(asan_clear_shadow): Fix formatting.
	(asan_function_start): Likewise.
	(asan_emit_stack_protection): Likewise.
	* doc/invoke.texi (asan-instrumentation-with-call-threshold):
	Update description.
	* internal-fn.c (expand_ASAN_CHECK): New function.
	* internal-fn.def (ASAN_CHECK): New internal function.
	* params.def (PARAM_ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD):
	Update description.
	(PARAM_ASAN_USE_AFTER_RETURN): Likewise.
	* tree.c: Small comment fix.

	* c-c++-common/asan/inc.c: Update test.
	* c-c++-common/asan/instrument-with-calls-2.c: Likewise.
	* c-c++-common/asan/no-redundant-instrumentation-1.c: Likewise.
	* c-c++-common/asan/no-redundant-instrumentation-2.c: Likewise.
	* c-c++-common/asan/no-redundant-instrumentation-3.c: Likewise.
	* c-c++-common/asan/no-redundant-instrumentation-4.c: Likewise.
	* c-c++-common/asan/no-redundant-instrumentation-5.c: Likewise.
	* c-c++-common/asan/no-redundant-instrumentation-6.c: Likewise.
	* c-c++-common/asan/no-redundant-instrumentation-7.c: Likewise.
	* c-c++-common/asan/no-redundant-instrumentation-8.c: Likewise.
	* c-c++-common/asan/no-redundant-instrumentation-9.c: Likewise.

diff --git a/gcc/asan.c b/gcc/asan.c
index 0789ad3..f55b024 100644
--- a/gcc/asan.c
+++ b/gcc/asan.c
@@ -242,18 +242,16 @@ static GTY(()) tree shadow_ptr_types[2];
 /* Decl for __asan_option_detect_stack_use_after_return.  */
 static GTY(()) tree asan_detect_stack_use_after_return;
 
-/* Number of instrumentations in current function so far.  */
-
-static int asan_num_accesses;
-
-/* Check whether we should replace inline instrumentation with calls.  */
-
-static inline bool
-use_calls_p ()
-{
-  return ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD < INT_MAX
-    && asan_num_accesses >= ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD;
-}
+/* Various flags for Asan builtins.  */
+enum asan_check_flags
+{
+  ASAN_CHECK_STORE = 1 << 0,
+  ASAN_CHECK_SCALAR_ACCESS = 1 << 1,
+  ASAN_CHECK_NON_ZERO_LEN = 1 << 2,
+  ASAN_CHECK_START_INSTRUMENTED = 1 << 3,
+  ASAN_CHECK_END_INSTRUMENTED = 1 << 4,
+  ASAN_CHECK_LAST
+};
 
 /* Hashtable support for memory references used by gimple
    statements.  */
@@ -942,7 +940,7 @@ asan_clear_shadow (rtx shadow_mem, HOST_WIDE_INT len)
 
   emit_move_insn (shadow_mem, const0_rtx);
   tmp = expand_simple_binop (Pmode, PLUS, addr, gen_int_mode (4, Pmode), addr,
-                             true, OPTAB_LIB_WIDEN);
+			     true, OPTAB_LIB_WIDEN);
   if (tmp != addr)
     emit_move_insn (addr, tmp);
   emit_cmp_and_jump_insns (addr, end, LT, NULL_RTX, Pmode, true, top_label);
@@ -957,7 +955,7 @@ asan_function_start (void)
   section *fnsec = function_section (current_function_decl);
   switch_to_section (fnsec);
   ASM_OUTPUT_DEBUG_LABEL (asm_out_file, "LASANPC",
-                         current_function_funcdef_no);
+			 current_function_funcdef_no);
 }
 
 /* Insert code to protect stack vars.  The prologue sequence should be emitted
@@ -1022,7 +1020,7 @@ asan_emit_stack_protection (rtx base, rtx pbase, unsigned int alignb,
     {
       use_after_return_class = floor_log2 (asan_frame_size - 1) - 5;
       /* __asan_stack_malloc_N guarantees alignment
-         N < 6 ? (64 << N) : 4096 bytes.  */
+	 N < 6 ? (64 << N) : 4096 bytes.  */
       if (alignb > (use_after_return_class < 6
 		    ? (64U << use_after_return_class) : 4096U))
 	use_after_return_class = -1;
@@ -1095,7 +1093,7 @@ asan_emit_stack_protection (rtx base, rtx pbase, unsigned int alignb,
   ASM_GENERATE_INTERNAL_LABEL (buf, "LASANPC", current_function_funcdef_no);
   id = get_identifier (buf);
   decl = build_decl (DECL_SOURCE_LOCATION (current_function_decl),
-                    VAR_DECL, id, char_type_node);
+		    VAR_DECL, id, char_type_node);
   SET_DECL_ASSEMBLER_NAME (decl, id);
   TREE_ADDRESSABLE (decl) = 1;
   TREE_READONLY (decl) = 1;
@@ -1552,55 +1550,6 @@ maybe_create_ssa_name (location_t loc, tree base, gimple_stmt_iterator *iter,
   return gimple_assign_lhs (g);
 }
 
-/* Instrument the memory access instruction using callbacks.
-   Parameters are similar to BUILD_CHECK_STMT.  */
-
-static void
-build_check_stmt_with_calls (location_t loc, tree base, tree len,
-			     HOST_WIDE_INT size_in_bytes, gimple_stmt_iterator *iter,
-			     bool before_p, bool is_store, bool is_scalar_access)
-{
-  gimple_stmt_iterator gsi = *iter;
-  tree base_ssa = maybe_create_ssa_name (loc, base, &gsi, before_p);
-
-  gimple g
-    = gimple_build_assign_with_ops (NOP_EXPR,
-				    make_ssa_name (pointer_sized_int_node, NULL),
-				    base_ssa, NULL_TREE);
-  gimple_set_location (g, loc);
-  if (before_p)
-    gsi_insert_before (&gsi, g, GSI_NEW_STMT);
-  else
-    gsi_insert_after (&gsi, g, GSI_NEW_STMT);
-  tree base_addr = gimple_assign_lhs (g);
-
-  int nargs;
-  tree fun
-    = check_func (is_store, is_scalar_access ? size_in_bytes : -1, &nargs);
-  if (nargs == 1)
-    g = gimple_build_call (fun, 1, base_addr);
-  else
-    {
-      gcc_assert (nargs == 2);
-      g = gimple_build_assign_with_ops (NOP_EXPR,
-					make_ssa_name (pointer_sized_int_node,
-						       NULL),
-					len, NULL_TREE);
-      gimple_set_location (g, loc);
-      gsi_insert_after (&gsi, g, GSI_NEW_STMT);
-      tree sz_arg = gimple_assign_lhs (g);
-      g = gimple_build_call (fun, nargs, base_addr, sz_arg);
-    }
-  gimple_set_location (g, loc);
-  gsi_insert_after (&gsi, g, GSI_NEW_STMT);
-
-  if (!before_p)
-    {
-      gsi_next (&gsi);
-      *iter = gsi;
-    }
-}
-
 /* Instrument the memory access instruction BASE.  Insert new
    statements before or after ITER.
 
@@ -1621,27 +1570,30 @@ build_check_stmt_with_calls (location_t loc, tree base, tree len,
    otherwise, it points to the statement logically following it.  */
 
 static void
-build_check_stmt (location_t location, tree base, tree len,
+build_check_stmt (location_t loc, tree base, tree len,
 		  HOST_WIDE_INT size_in_bytes, gimple_stmt_iterator *iter,
-		  bool non_zero_len_p, bool before_p, bool is_store,
+		  bool is_non_zero_len, bool before_p, bool is_store,
 		  bool is_scalar_access, unsigned int align = 0,
 		  bool start_instrumented = false,
 		  bool end_instrumented = false)
 {
   gimple_stmt_iterator gsi = *iter;
   gimple g;
-  tree uintptr_type
-    = build_nonstandard_integer_type (TYPE_PRECISION (TREE_TYPE (base)), 1);
 
-  gcc_assert (!(size_in_bytes > 0 && !non_zero_len_p));
+  gcc_assert (!(size_in_bytes > 0 && !is_non_zero_len));
 
   if (start_instrumented && end_instrumented)
     {
       if (!before_p)
-        gsi_next (iter);
+	gsi_next (iter);
       return;
     }
 
+  gsi = *iter;
+
+  base = unshare_expr (base);
+  base = maybe_create_ssa_name (loc, base, &gsi, before_p);
+
   if (len)
     len = unshare_expr (len);
   else
@@ -1653,9 +1605,8 @@ build_check_stmt (location_t location, tree base, tree len,
   if (size_in_bytes > 1)
     {
       if ((size_in_bytes & (size_in_bytes - 1)) != 0
-	  || !is_scalar_access
 	  || size_in_bytes > 16)
-	size_in_bytes = -1;
+	is_scalar_access = false;
       else if (align && align < size_in_bytes * BITS_PER_UNIT)
 	{
 	  /* On non-strict alignment targets, if
@@ -1666,189 +1617,34 @@ build_check_stmt (location_t location, tree base, tree len,
 	  if (size_in_bytes != 16
 	      || STRICT_ALIGNMENT
 	      || align < 8 * BITS_PER_UNIT)
-	    size_in_bytes = -1;
-	}
-    }
-
-  HOST_WIDE_INT real_size_in_bytes = size_in_bytes == -1 ? 1 : size_in_bytes;
-
-  tree shadow_ptr_type = shadow_ptr_types[real_size_in_bytes == 16 ? 1 : 0];
-  tree shadow_type = TREE_TYPE (shadow_ptr_type);
-
-  base = unshare_expr (base);
-
-  if (use_calls_p ())
-    {
-      gsi = *iter;
-      build_check_stmt_with_calls (location, base, len, size_in_bytes, iter,
-				   before_p, is_store, is_scalar_access);
-      return;
-    }
-
-  ++asan_num_accesses;
-
-  if (!non_zero_len_p)
-    {
-      gcc_assert (before_p);
-
-      /* So, the length of the memory area to asan-protect is
-	 non-constant.  Let's guard the generated instrumentation code
-	 like:
-
-	 if (len != 0)
-	   {
-	     //asan instrumentation code goes here.
-	   }
-	 // falltrough instructions, starting with *ITER.  */
-
-      g = gimple_build_cond (NE_EXPR,
-			     len,
-			     build_int_cst (TREE_TYPE (len), 0),
-			     NULL_TREE, NULL_TREE);
-      gimple_set_location (g, location);
-
-      basic_block then_bb, fallthrough_bb;
-      insert_if_then_before_iter (g, iter, /*then_more_likely_p=*/true,
-				  &then_bb, &fallthrough_bb);
-      /* Note that fallthrough_bb starts with the statement that was
-	 pointed to by ITER.  */
-
-      /* The 'then block' of the 'if (len != 0) condition is where
-	 we'll generate the asan instrumentation code now.  */
-      gsi = gsi_last_bb (then_bb);
-      build_check_stmt (location, base, len, size_in_bytes, &gsi,
-			/*non_zero_len_p*/true, /*before_p*/true, is_store,
-			is_scalar_access, align,
-			start_instrumented, end_instrumented);
-      return;
-    }
-
-  /* Get an iterator on the point where we can add the condition
-     statement for the instrumentation.  */
-  basic_block then_bb, else_bb;
-  gsi = create_cond_insert_point (&gsi, before_p,
-				  /*then_more_likely_p=*/false,
-				  /*create_then_fallthru_edge=*/false,
-				  &then_bb,
-				  &else_bb);
-
-  tree base_ssa = maybe_create_ssa_name (location, base, &gsi,
-					 /*before_p*/false);
-
-  g = gimple_build_assign_with_ops (NOP_EXPR,
-				    make_ssa_name (uintptr_type, NULL),
-				    base_ssa, NULL_TREE);
-  gimple_set_location (g, location);
-  gsi_insert_after (&gsi, g, GSI_NEW_STMT);
-  tree base_addr = gimple_assign_lhs (g);
-
-  tree t = NULL_TREE;
-  if (real_size_in_bytes >= 8)
-    {
-      tree shadow = build_shadow_mem_access (&gsi, location, base_addr,
-					     shadow_ptr_type);
-      t = shadow;
-    }
-  else
-    {
-      /* Slow path for 1, 2 and 4 byte accesses.  */
-
-      if (!start_instrumented)
-	{
-	  /* Test (shadow != 0)
-		  & ((base_addr & 7) + (real_size_in_bytes - 1)) >= shadow).  */
-	  tree shadow = build_shadow_mem_access (&gsi, location, base_addr,
-						 shadow_ptr_type);
-	  gimple shadow_test = build_assign (NE_EXPR, shadow, 0);
-	  gimple_seq seq = NULL;
-	  gimple_seq_add_stmt (&seq, shadow_test);
-	  gimple_seq_add_stmt (&seq, build_assign (BIT_AND_EXPR, base_addr, 7));
-	  gimple_seq_add_stmt (&seq, build_type_cast (shadow_type,
-						      gimple_seq_last (seq)));
-	  if (real_size_in_bytes > 1)
-	    gimple_seq_add_stmt (&seq,
-				 build_assign (PLUS_EXPR, gimple_seq_last (seq),
-					       real_size_in_bytes - 1));
-	  gimple_seq_add_stmt (&seq, build_assign (GE_EXPR,
-						   gimple_seq_last (seq),
-						   shadow));
-	  gimple_seq_add_stmt (&seq, build_assign (BIT_AND_EXPR, shadow_test,
-						   gimple_seq_last (seq)));
-	  t = gimple_assign_lhs (gimple_seq_last (seq));
-	  gimple_seq_set_location (seq, location);
-	  gsi_insert_seq_after (&gsi, seq, GSI_CONTINUE_LINKING);
-	}
-
-      /* For non-constant, misaligned or otherwise weird access sizes,
-	 check first and last byte.  */
-      if (size_in_bytes == -1 && !end_instrumented)
-	{
-	  g = gimple_build_assign_with_ops (MINUS_EXPR,
-					    make_ssa_name (uintptr_type, NULL),
-					    len,
-					    build_int_cst (uintptr_type, 1));
-	  gimple_set_location (g, location);
-	  gsi_insert_after (&gsi, g, GSI_NEW_STMT);
-	  tree last = gimple_assign_lhs (g);
-	  g = gimple_build_assign_with_ops (PLUS_EXPR,
-					    make_ssa_name (uintptr_type, NULL),
-					    base_addr,
-					    last);
-	  gimple_set_location (g, location);
-	  gsi_insert_after (&gsi, g, GSI_NEW_STMT);
-	  tree base_end_addr = gimple_assign_lhs (g);
-
-	  tree shadow = build_shadow_mem_access (&gsi, location, base_end_addr,
-						 shadow_ptr_type);
-	  gimple shadow_test = build_assign (NE_EXPR, shadow, 0);
-	  gimple_seq seq = NULL;
-	  gimple_seq_add_stmt (&seq, shadow_test);
-	  gimple_seq_add_stmt (&seq, build_assign (BIT_AND_EXPR,
-						   base_end_addr, 7));
-	  gimple_seq_add_stmt (&seq, build_type_cast (shadow_type,
-						      gimple_seq_last (seq)));
-	  gimple_seq_add_stmt (&seq, build_assign (GE_EXPR,
-						   gimple_seq_last (seq),
-						   shadow));
-	  gimple_seq_add_stmt (&seq, build_assign (BIT_AND_EXPR, shadow_test,
-						   gimple_seq_last (seq)));
-	  if (!start_instrumented)
-	    gimple_seq_add_stmt (&seq, build_assign (BIT_IOR_EXPR, t,
-						     gimple_seq_last (seq)));
-	  t = gimple_assign_lhs (gimple_seq_last (seq));
-	  gimple_seq_set_location (seq, location);
-	  gsi_insert_seq_after (&gsi, seq, GSI_CONTINUE_LINKING);
+	    is_scalar_access = false;
 	}
     }
 
-  g = gimple_build_cond (NE_EXPR, t, build_int_cst (TREE_TYPE (t), 0),
-			 NULL_TREE, NULL_TREE);
-  gimple_set_location (g, location);
-  gsi_insert_after (&gsi, g, GSI_NEW_STMT);
-
-  /* Generate call to the run-time library (e.g. __asan_report_load8).  */
-  gsi = gsi_start_bb (then_bb);
-  int nargs;
-  tree fun = report_error_func (is_store, is_scalar_access ? size_in_bytes : -1,
-				&nargs);
-  if (nargs == 1)
-      g = gimple_build_call (fun, 1, base_addr);
+  HOST_WIDE_INT flags = 0;
+  if (is_store)
+    flags |= ASAN_CHECK_STORE;
+  if (is_non_zero_len)
+    flags |= ASAN_CHECK_NON_ZERO_LEN;
+  if (is_scalar_access)
+    flags |= ASAN_CHECK_SCALAR_ACCESS;
+  if (start_instrumented)
+    flags |= ASAN_CHECK_START_INSTRUMENTED;
+  if (end_instrumented)
+    flags |= ASAN_CHECK_END_INSTRUMENTED;
+
+  g = gimple_build_call_internal (IFN_ASAN_CHECK, 3,
+				  build_int_cst (integer_type_node, flags),
+				  base, len);
+  gimple_set_location (g, loc);
+  if (before_p)
+    gsi_insert_before (&gsi, g, GSI_SAME_STMT);
   else
     {
-      gcc_assert (nargs == 2);
-      g = gimple_build_assign_with_ops (NOP_EXPR,
-					make_ssa_name (pointer_sized_int_node,
-						       NULL),
-					len, NULL_TREE);
-      gimple_set_location (g, location);
       gsi_insert_after (&gsi, g, GSI_NEW_STMT);
-      tree sz_arg = gimple_assign_lhs (g);
-      g = gimple_build_call (fun, nargs, base_addr, sz_arg);
+      gsi_next (&gsi);
+      *iter = gsi;
     }
-  gimple_set_location (g, location);
-  gsi_insert_after (&gsi, g, GSI_NEW_STMT);
-
-  *iter = gsi_start_bb (else_bb);
 }
 
 /* If T represents a memory access, add instrumentation code before ITER.
@@ -1942,7 +1738,7 @@ instrument_derefs (gimple_stmt_iterator *iter, tree t,
     {
       unsigned int align = get_object_alignment (t);
       build_check_stmt (location, base, NULL_TREE, size_in_bytes, iter,
-			/*non_zero_len_p*/size_in_bytes > 0, /*before_p=*/true,
+			/*is_non_zero_len*/size_in_bytes > 0, /*before_p=*/true,
 			is_store, /*is_scalar_access*/true, align);
       update_mem_ref_hash_table (base, size_in_bytes);
       update_mem_ref_hash_table (t, size_in_bytes);
@@ -1980,7 +1776,7 @@ instrument_mem_region_access (tree base, tree len,
   HOST_WIDE_INT size_in_bytes = tree_fits_shwi_p (len) ? tree_to_shwi (len) : -1;
 
   build_check_stmt (location, base, len, size_in_bytes, iter,
-		    /*non_zero_len_p*/size_in_bytes > 0, /*before_p*/true,
+		    /*is_non_zero_len*/size_in_bytes > 0, /*before_p*/true,
 		    is_store, /*is_scalar_access*/false, /*align*/0,
 		    start_instrumented, end_instrumented);
 
@@ -2037,7 +1833,7 @@ instrument_strlen_call (gimple_stmt_iterator *iter)
   gsi_insert_before (iter, str_arg_ssa, GSI_SAME_STMT);
 
   build_check_stmt (loc, gimple_assign_lhs (str_arg_ssa), NULL_TREE, 1, iter,
-		    /*non_zero_len_p*/true, /*before_p=*/true,
+		    /*is_non_zero_len*/true, /*before_p=*/true,
 		    /*is_store=*/false, /*is_scalar_access*/true, /*align*/0,
 		    start_instrumented, start_instrumented);
 
@@ -2050,7 +1846,7 @@ instrument_strlen_call (gimple_stmt_iterator *iter)
   gsi_insert_after (iter, g, GSI_NEW_STMT);
 
   build_check_stmt (loc, gimple_assign_lhs (g), NULL_TREE, 1, iter,
-		    /*non_zero_len_p*/true, /*before_p=*/false,
+		    /*is_non_zero_len*/true, /*before_p=*/false,
 		    /*is_store=*/false, /*is_scalar_access*/true, /*align*/0);
 
   return true;
@@ -2618,6 +2414,215 @@ asan_finish_file (void)
   flag_sanitize |= SANITIZE_ADDRESS;
 }
 
+/* Expand the ASAN_{LOAD,STORE} builtins.  */
+
+static bool
+asan_expand_check_ifn (gimple_stmt_iterator *iter, bool use_calls)
+{
+  gimple g = gsi_stmt (*iter);
+  location_t loc = gimple_location (g);
+
+  HOST_WIDE_INT flags = tree_to_shwi (gimple_call_arg (g, 0));
+  gcc_assert (flags < ASAN_CHECK_LAST);
+  bool is_scalar_access = (flags & ASAN_CHECK_SCALAR_ACCESS) != 0;
+  bool is_store = (flags & ASAN_CHECK_STORE) != 0;
+  bool is_non_zero_len = (flags & ASAN_CHECK_NON_ZERO_LEN) != 0;
+  bool start_instrumented = (flags & ASAN_CHECK_START_INSTRUMENTED) != 0;
+  bool end_instrumented = (flags & ASAN_CHECK_END_INSTRUMENTED) != 0;
+
+  tree base = gimple_call_arg (g, 1);
+  tree len = gimple_call_arg (g, 2);
+
+  HOST_WIDE_INT size_in_bytes
+    = is_scalar_access && tree_fits_shwi_p (len) ? tree_to_shwi (len) : -1;
+
+  if (use_calls)
+    {
+      /* Instrument using callbacks.  */
+      gimple g
+	= gimple_build_assign_with_ops (NOP_EXPR,
+					make_ssa_name (pointer_sized_int_node,
+					NULL),
+					base, NULL_TREE);
+      gimple_set_location (g, loc);
+      gsi_insert_before (iter, g, GSI_SAME_STMT);
+      tree base_addr = gimple_assign_lhs (g);
+
+      int nargs;
+      tree fun = check_func (is_store, size_in_bytes, &nargs);
+      if (nargs == 1)
+	g = gimple_build_call (fun, 1, base_addr);
+      else
+	{
+	  gcc_assert (nargs == 2);
+	  g = gimple_build_assign_with_ops (NOP_EXPR,
+					    make_ssa_name (pointer_sized_int_node,
+							   NULL),
+					    len, NULL_TREE);
+	  gimple_set_location (g, loc);
+	  gsi_insert_before (iter, g, GSI_SAME_STMT);
+	  tree sz_arg = gimple_assign_lhs (g);
+	  g = gimple_build_call (fun, nargs, base_addr, sz_arg);
+	}
+      gimple_set_location (g, loc);
+      gsi_replace (iter, g, false);
+      return false;
+    }
+
+  HOST_WIDE_INT real_size_in_bytes = size_in_bytes == -1 ? 1 : size_in_bytes;
+
+  tree uintptr_type
+    = build_nonstandard_integer_type (TYPE_PRECISION (TREE_TYPE (base)), 1);
+
+  tree shadow_ptr_type = shadow_ptr_types[real_size_in_bytes == 16 ? 1 : 0];
+  tree shadow_type = TREE_TYPE (shadow_ptr_type);
+
+  gimple_stmt_iterator gsi = *iter;
+
+  if (!is_non_zero_len)
+    {
+      /* So, the length of the memory area to asan-protect is
+	 non-constant.  Let's guard the generated instrumentation code
+	 like:
+
+	 if (len != 0)
+	   {
+	     //asan instrumentation code goes here.
+	   }
+	 // falltrough instructions, starting with *ITER.  */
+
+      g = gimple_build_cond (NE_EXPR,
+			    len,
+			    build_int_cst (TREE_TYPE (len), 0),
+			    NULL_TREE, NULL_TREE);
+      gimple_set_location (g, loc);
+
+      basic_block then_bb, fallthrough_bb;
+      insert_if_then_before_iter (g, iter, /*then_more_likely_p=*/true,
+				 &then_bb, &fallthrough_bb);
+      /* Note that fallthrough_bb starts with the statement that was
+	pointed to by ITER.  */
+
+      /* The 'then block' of the 'if (len != 0) condition is where
+	we'll generate the asan instrumentation code now.  */
+      gsi = gsi_last_bb (then_bb);
+    }
+
+  /* Get an iterator on the point where we can add the condition
+     statement for the instrumentation.  */
+  basic_block then_bb, else_bb;
+  gsi = create_cond_insert_point (&gsi, /*before_p*/false,
+				  /*then_more_likely_p=*/false,
+				  /*create_then_fallthru_edge=*/false,
+				  &then_bb,
+				  &else_bb);
+
+  g = gimple_build_assign_with_ops (NOP_EXPR,
+				    make_ssa_name (pointer_sized_int_node,
+						   NULL),
+				    base, NULL_TREE);
+  gimple_set_location (g, loc);
+  gsi_insert_before (&gsi, g, GSI_NEW_STMT);
+  tree base_addr = gimple_assign_lhs (g);
+
+  tree t = NULL_TREE;
+  if (real_size_in_bytes >= 8)
+    {
+      tree shadow = build_shadow_mem_access (&gsi, loc, base_addr,
+					     shadow_ptr_type);
+      t = shadow;
+    }
+  else
+    {
+      /* Slow path for 1, 2 and 4 byte accesses.  */
+
+      if (!start_instrumented)
+	{
+	  /* Test (shadow != 0)
+	     & ((base_addr & 7) + (real_size_in_bytes - 1)) >= shadow).  */
+	  tree shadow = build_shadow_mem_access (&gsi, loc, base_addr,
+						 shadow_ptr_type);
+	  gimple shadow_test = build_assign (NE_EXPR, shadow, 0);
+	  gimple_seq seq = NULL;
+	  gimple_seq_add_stmt (&seq, shadow_test);
+	  gimple_seq_add_stmt (&seq, build_assign (BIT_AND_EXPR, base_addr, 7));
+	  gimple_seq_add_stmt (&seq, build_type_cast (shadow_type,
+						      gimple_seq_last (seq)));
+	  if (real_size_in_bytes > 1)
+	    gimple_seq_add_stmt (&seq,
+				 build_assign (PLUS_EXPR, gimple_seq_last (seq),
+					       real_size_in_bytes - 1));
+	  gimple_seq_add_stmt (&seq, build_assign (GE_EXPR,
+						   gimple_seq_last (seq),
+						   shadow));
+	  gimple_seq_add_stmt (&seq, build_assign (BIT_AND_EXPR, shadow_test,
+						   gimple_seq_last (seq)));
+	  t = gimple_assign_lhs (gimple_seq_last (seq));
+	  gimple_seq_set_location (seq, loc);
+	  gsi_insert_seq_after (&gsi, seq, GSI_CONTINUE_LINKING);
+	}
+
+      /* For non-constant, misaligned or otherwise weird access sizes,
+	 check first and last byte.  */
+      if (size_in_bytes == -1 && !end_instrumented)
+	{
+	  g = gimple_build_assign_with_ops (MINUS_EXPR,
+					    make_ssa_name (uintptr_type, NULL),
+					    len,
+					    build_int_cst (uintptr_type, 1));
+	  gimple_set_location (g, loc);
+	  gsi_insert_after (&gsi, g, GSI_NEW_STMT);
+	  tree last = gimple_assign_lhs (g);
+	  g = gimple_build_assign_with_ops (PLUS_EXPR,
+					    make_ssa_name (uintptr_type, NULL),
+					    base_addr,
+					    last);
+	  gimple_set_location (g, loc);
+	  gsi_insert_after (&gsi, g, GSI_NEW_STMT);
+	  tree base_end_addr = gimple_assign_lhs (g);
+
+	  tree shadow = build_shadow_mem_access (&gsi, loc, base_end_addr,
+						 shadow_ptr_type);
+	  gimple shadow_test = build_assign (NE_EXPR, shadow, 0);
+	  gimple_seq seq = NULL;
+	  gimple_seq_add_stmt (&seq, shadow_test);
+	  gimple_seq_add_stmt (&seq, build_assign (BIT_AND_EXPR,
+						   base_end_addr, 7));
+	  gimple_seq_add_stmt (&seq, build_type_cast (shadow_type,
+						      gimple_seq_last (seq)));
+	  gimple_seq_add_stmt (&seq, build_assign (GE_EXPR,
+						   gimple_seq_last (seq),
+						   shadow));
+	  gimple_seq_add_stmt (&seq, build_assign (BIT_AND_EXPR, shadow_test,
+						   gimple_seq_last (seq)));
+	  if (!start_instrumented)
+	    gimple_seq_add_stmt (&seq, build_assign (BIT_IOR_EXPR, t,
+						     gimple_seq_last (seq)));
+	  t = gimple_assign_lhs (gimple_seq_last (seq));
+	  gimple_seq_set_location (seq, loc);
+	  gsi_insert_seq_after (&gsi, seq, GSI_CONTINUE_LINKING);
+	}
+    }
+
+  g = gimple_build_cond (NE_EXPR, t, build_int_cst (TREE_TYPE (t), 0),
+			 NULL_TREE, NULL_TREE);
+  gimple_set_location (g, loc);
+  gsi_insert_after (&gsi, g, GSI_NEW_STMT);
+
+  /* Generate call to the run-time library (e.g. __asan_report_load8).  */
+  gsi = gsi_start_bb (then_bb);
+  int nargs;
+  tree fun = report_error_func (is_store, size_in_bytes, &nargs);
+  g = gimple_build_call (fun, nargs, base_addr, len);
+  gimple_set_location (g, loc);
+  gsi_insert_after (&gsi, g, GSI_NEW_STMT);
+
+  gsi_remove (iter, true);
+  *iter = gsi_start_bb (else_bb);
+
+  return true;
+}
+
 /* Instrument the current function.  */
 
 static unsigned int
@@ -2625,7 +2630,6 @@ asan_instrument (void)
 {
   if (shadow_ptr_types[0] == NULL_TREE)
     asan_init_shadow_ptr_types ();
-  asan_num_accesses = 0;
   transform_statements ();
   return 0;
 }
@@ -2730,25 +2734,54 @@ execute_sanopt (void)
 {
   basic_block bb;
 
+  int asan_num_accesses = 0;
+  if (flag_sanitize & SANITIZE_ADDRESS)
+    {
+      gimple_stmt_iterator gsi;
+      FOR_EACH_BB_FN (bb, cfun)
+	for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+	  {
+ 	    gimple stmt = gsi_stmt (gsi);
+	    if (is_gimple_call (stmt) && gimple_call_internal_p (stmt)
+		&& gimple_call_internal_fn (stmt) == IFN_ASAN_CHECK)
+	      ++asan_num_accesses;
+	  }
+    }
+
+  bool use_calls = ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD < INT_MAX
+    && asan_num_accesses >= ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD;
+
   FOR_EACH_BB_FN (bb, cfun)
     {
       gimple_stmt_iterator gsi;
-      for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+      for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); )
 	{
 	  gimple stmt = gsi_stmt (gsi);
+	  bool no_next = false;
 
 	  if (!is_gimple_call (stmt))
-	    continue;
+	    {
+	      gsi_next (&gsi);
+	      continue;
+	    }
 
 	  if (gimple_call_internal_p (stmt))
-	    switch (gimple_call_internal_fn (stmt))
-	      {
-	      case IFN_UBSAN_NULL:
-		ubsan_expand_null_ifn (gsi);
-		break;
-	      default:
-		break;
-	      }
+	    {
+	      enum internal_fn ifn = gimple_call_internal_fn (stmt);
+	      switch (ifn)
+		{
+		case IFN_UBSAN_NULL:
+		  ubsan_expand_null_ifn (gsi);
+		  break;
+		case IFN_ASAN_CHECK:
+		  {
+		    no_next = asan_expand_check_ifn (&gsi, use_calls);
+		    break;
+		  }
+		default:
+		  break;
+		}
+	    }
 
 	  if (dump_file && (dump_flags & TDF_DETAILS))
 	    {
@@ -2756,6 +2789,9 @@ execute_sanopt (void)
 	      print_gimple_stmt (dump_file, stmt, 0, dump_flags);
 	      fprintf (dump_file, "\n");
 	    }
+
+	  if (!no_next)
+	    gsi_next (&gsi);
 	}
     }
   return 0;
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 179f273..bea8be2 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -10140,9 +10140,9 @@ To disable use-after-return detection use
 @option{--param asan-use-after-return=0}.
 
 @item asan-instrumentation-with-call-threshold
-Once number of memory accesses  in function becomes greater
-or equal than this number, use callbacks instead of
-generating inline code.  E.g. to disable inline code use
+If number of memory accesses in function being instrumented
+is greater or equal to this number, use callbacks instead of inline checks.
+E.g. to disable inline code use
 @option{--param asan-instrumentation-with-call-threshold=0}.
 
 @end table
diff --git a/gcc/internal-fn.c b/gcc/internal-fn.c
index 5b881f1..0749dce 100644
--- a/gcc/internal-fn.c
+++ b/gcc/internal-fn.c
@@ -173,6 +173,14 @@ expand_UBSAN_NULL (gimple stmt ATTRIBUTE_UNUSED)
   gcc_unreachable ();
 }
 
+/* This should get expanded in the sanopt pass.  */
+
+static void
+expand_ASAN_CHECK (gimple stmt ATTRIBUTE_UNUSED)
+{
+  gcc_unreachable ();
+}
+
 /* Add sub/add overflow checking to the statement STMT.
    CODE says whether the operation is +, or -.  */
 
diff --git a/gcc/internal-fn.def b/gcc/internal-fn.def
index f60a9b0..2156e24 100644
--- a/gcc/internal-fn.def
+++ b/gcc/internal-fn.def
@@ -54,3 +54,4 @@ DEF_INTERNAL_FN (UBSAN_CHECK_SUB, ECF_CONST | ECF_LEAF | ECF_NOTHROW, NULL)
 DEF_INTERNAL_FN (UBSAN_CHECK_MUL, ECF_CONST | ECF_LEAF | ECF_NOTHROW, NULL)
 DEF_INTERNAL_FN (ABNORMAL_DISPATCHER, ECF_NORETURN, NULL)
 DEF_INTERNAL_FN (BUILTIN_EXPECT, ECF_CONST | ECF_LEAF | ECF_NOTHROW, NULL)
+DEF_INTERNAL_FN (ASAN_CHECK, ECF_TM_PURE | ECF_LEAF | ECF_NOTHROW, ".W..")
diff --git a/gcc/params.def b/gcc/params.def
index a258c08..b3a1ffb 100644
--- a/gcc/params.def
+++ b/gcc/params.def
@@ -1081,14 +1081,14 @@ DEFPARAM (PARAM_ASAN_MEMINTRIN,
 
 DEFPARAM (PARAM_ASAN_USE_AFTER_RETURN,
          "asan-use-after-return",
-         "Enable asan builtin functions protection",
+         "Enable asan detection of use-after-return bugs",
          1, 0, 1)
 
 DEFPARAM (PARAM_ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD,
          "asan-instrumentation-with-call-threshold",
-         "Use callbacks instead of inline code once number of accesses "
-         " in function becomes greater or equal than this threshold",
-         INT_MAX, 0, INT_MAX)
+         "Use callbacks instead of inline code if number of accesses "
+         "in function becomes greater or equal to this number",
+         INT_MAX, 0, INT_MAX)
 
 DEFPARAM (PARAM_UNINIT_CONTROL_DEP_ATTEMPTS,
 	  "uninit-control-dep-attempts",
diff --git a/gcc/testsuite/c-c++-common/asan/inc.c b/gcc/testsuite/c-c++-common/asan/inc.c
index b9c6734..36cc3d8 100644
--- a/gcc/testsuite/c-c++-common/asan/inc.c
+++ b/gcc/testsuite/c-c++-common/asan/inc.c
@@ -16,6 +16,6 @@ main ()
   return 0;
 }
 
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report" 1 "asan0" } }  */
-/* { dg-final { scan-tree-dump "__builtin___asan_report_load4" "asan0" } }  */
+/* { dg-final { scan-tree-dump-times "ASAN_" 1 "asan0" } }  */
+/* { dg-final { scan-tree-dump "ASAN_CHECK \\(.*, 4\\);" "asan0" } }  */
 /* { dg-final { cleanup-tree-dump "asan0" } } */
diff --git a/gcc/testsuite/c-c++-common/asan/instrument-with-calls-2.c b/gcc/testsuite/c-c++-common/asan/instrument-with-calls-2.c
index 570f796..04fdad0 100644
--- a/gcc/testsuite/c-c++-common/asan/instrument-with-calls-2.c
+++ b/gcc/testsuite/c-c++-common/asan/instrument-with-calls-2.c
@@ -9,8 +9,8 @@ void f(int *a, int *b) {
   x = *b;
 }
 
-/* { dg-final { scan-assembler-not "__asan_store4" } } */
-/* { dg-final { scan-assembler "__asan_report_store4" } } */
+/* { dg-final { scan-assembler "__asan_store4" } } */
+/* { dg-final { scan-assembler-not "__asan_report_store4" } } */
 /* { dg-final { scan-assembler "__asan_load4" } } */
 /* { dg-final { scan-assembler-not "__asan_report_load4" } } */
 /* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-1.c b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-1.c
index c7c594e..028f8d7 100644
--- a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-1.c
+++ b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-1.c
@@ -2,7 +2,7 @@
    location in the same basic block, the second reference should not
    be instrumented by the Address Sanitizer.  */
 
-/* { dg-options "-fdump-tree-asan0" } */
+/* { dg-options "-fdump-tree-sanopt" } */
 /* { dg-do compile } */
 /* { dg-skip-if "" { *-*-* } { "*" } { "-O0" } } */
 
@@ -62,7 +62,7 @@ main ()
   return test0 () && test1 (0);
 }
 
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store1" 3 "asan0" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store_n" 2 "asan0" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load" 1 "asan0" }  } */
-/* { dg-final { cleanup-tree-dump "asan0" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store1" 3 "sanopt" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store_n" 2 "sanopt" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load" 1 "sanopt" }  } */
+/* { dg-final { cleanup-tree-dump "sanopt" } } */
diff --git a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-2.c b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-2.c
index 143312f..a58411c 100644
--- a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-2.c
+++ b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-2.c
@@ -3,7 +3,7 @@
    be instrumented by the Address Sanitizer.  But in case of access to
    overlapping regions we must be precise.  */
 
-/* { dg-options "-fdump-tree-asan0" } */
+/* { dg-options "-fdump-tree-sanopt" } */
 /* { dg-do compile } */
 /* { dg-skip-if "" { *-*-* } { "*" } { "-O0" } } */
 
@@ -20,7 +20,7 @@ main ()
   __builtin_memset (tab, 1, 3);
 }
 
-/* { dg-final { scan-tree-dump-times "& 7" 3 "asan0" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store_n" 2 "asan0" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report" 2 "asan0" }  } */
-/* { dg-final { cleanup-tree-dump "asan0" } } */
+/* { dg-final { scan-tree-dump-times "& 7" 3 "sanopt" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store_n" 2 "sanopt" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report" 2 "sanopt" }  } */
+/* { dg-final { cleanup-tree-dump "sanopt" } } */
diff --git a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-3.c b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-3.c
index 420a263..5193ae0 100644
--- a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-3.c
+++ b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-3.c
@@ -1,4 +1,4 @@
-/* { dg-options "-fdump-tree-asan0" } */
+/* { dg-options "-fdump-tree-sanopt" } */
 /* { dg-do compile } */
 /* { dg-skip-if "" { *-*-* } { "*" } { "-O0" } } */
 
@@ -12,7 +12,7 @@ foo (__INT32_TYPE__ *p)
   return ret; 
 }
 
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report" 2 "asan0" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load1" 1 "asan0" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store" 1 "asan0" } } */
-/* { dg-final { cleanup-tree-dump "asan0" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report" 2 "sanopt" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load1" 1 "sanopt" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store" 1 "sanopt" } } */
+/* { dg-final { cleanup-tree-dump "sanopt" } } */
diff --git a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-4.c b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-4.c
index da91cd5..c3632aa 100644
--- a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-4.c
+++ b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-4.c
@@ -1,4 +1,4 @@
-/* { dg-options "-fdump-tree-asan0" } */
+/* { dg-options "-fdump-tree-sanopt" } */
 /* { dg-do compile } */
 /* { dg-skip-if "" { *-*-* } { "*" } { "-O0" } } */
 
@@ -10,8 +10,8 @@ foo  (int *a, char *b, char *c)
   /* For a total of 5 checks.  */
 }
 
-/* { dg-final { scan-tree-dump-times "& 7" 5 "asan0" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load1" 1 "asan0" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load_n" 1 "asan0" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store_n" 1 "asan0" } } */
-/* { dg-final { cleanup-tree-dump "asan0" } } */
+/* { dg-final { scan-tree-dump-times "& 7" 5 "sanopt" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load1" 1 "sanopt" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load_n" 1 "sanopt" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store_n" 1 "sanopt" } } */
+/* { dg-final { cleanup-tree-dump "sanopt" } } */
diff --git a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-5.c b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-5.c
index 134be66..077ea34 100644
--- a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-5.c
+++ b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-5.c
@@ -1,4 +1,4 @@
-/* { dg-options "-fdump-tree-asan0" } */
+/* { dg-options "-fdump-tree-sanopt" } */
 /* { dg-do compile } */
 /* { dg-skip-if "" { *-*-* } { "*" } { "-O0" } } */
 
@@ -10,9 +10,9 @@ foo  (int *a, char *b, char *c)
   /* For a total of 5 checks.  */
 }
 
-/* { dg-final { scan-tree-dump-times "& 7" 5 "asan0" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load1" 1 "asan0" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load4" 1 "asan0" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load_n" 1 "asan0" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store_n" 1 "asan0" } } */
-/* { dg-final { cleanup-tree-dump "asan0" } } */
+/* { dg-final { scan-tree-dump-times "& 7" 5 "sanopt" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load1" 1 "sanopt" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load4" 1 "sanopt" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load_n" 1 "sanopt" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store_n" 1 "sanopt" } } */
+/* { dg-final { cleanup-tree-dump "sanopt" } } */
diff --git a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-6.c b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-6.c
index 55c8ee3..6d87104 100644
--- a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-6.c
+++ b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-6.c
@@ -1,4 +1,4 @@
-/* { dg-options "-fdump-tree-asan0" } */
+/* { dg-options "-fdump-tree-sanopt" } */
 /* { dg-do compile } */
 /* { dg-skip-if "" { *-*-* } { "*" } { "-O0" } } */
 
@@ -12,9 +12,9 @@ foo  (int *a, char *b, char *c)
   /* For a total of 8 checks.  */
 }
 
-/* { dg-final { scan-tree-dump-times "& 7" 8 "asan0" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load1" 1 "asan0" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load4" 2 "asan0" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load_n" 2 "asan0" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store_n" 2 "asan0" } } */
-/* { dg-final { cleanup-tree-dump "asan0" } } */
+/* { dg-final { scan-tree-dump-times "& 7" 8 "sanopt" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load1" 1 "sanopt" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load4" 2 "sanopt" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load_n" 2 "sanopt" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store_n" 2 "sanopt" } } */
+/* { dg-final { cleanup-tree-dump "sanopt" } } */
diff --git a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-7.c b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-7.c
index a04956d..5baa10d 100644
--- a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-7.c
+++ b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-7.c
@@ -1,4 +1,4 @@
-/* { dg-options "-fdump-tree-asan0" } */
+/* { dg-options "-fdump-tree-sanopt" } */
 /* { dg-do compile } */
 /* { dg-skip-if "" { *-*-* } { "*" } { "-O0" } } */
 
@@ -21,7 +21,7 @@ foo  (int *a, char *b, char *c)
   return d;
 }
 
-/* { dg-final { scan-tree-dump-times "& 7" 6 "asan0" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load_n" 4 "asan0" } } */
-/* { dg-final { scan-tree-dump-not "__builtin___asan_report_store" "asan0" } } */
-/* { dg-final { cleanup-tree-dump "asan0" } } */
+/* { dg-final { scan-tree-dump-times "& 7" 6 "sanopt" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load_n" 4 "sanopt" } } */
+/* { dg-final { scan-tree-dump-not "__builtin___asan_report_store" "sanopt" } } */
+/* { dg-final { cleanup-tree-dump "sanopt" } } */
diff --git a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-8.c b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-8.c
index 308a133..2a4c081 100644
--- a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-8.c
+++ b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-8.c
@@ -1,4 +1,4 @@
-/* { dg-options "-fdump-tree-asan0" } */
+/* { dg-options "-fdump-tree-sanopt" } */
 /* { dg-do compile } */
 /* { dg-skip-if "" { *-*-* } { "*" } { "-O0" } } */
 
@@ -12,9 +12,9 @@ foo  (int *a, char *b, char *c)
   /* For a total of 5 checks.  */
 }
 
-/* { dg-final { scan-tree-dump-times "& 7" 5 "asan0" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load1" 1 "asan0" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load4" 1 "asan0" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load_n" 1 "asan0" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store_n" 1 "asan0" } } */
-/* { dg-final { cleanup-tree-dump "asan0" } } */
+/* { dg-final { scan-tree-dump-times "& 7" 5 "sanopt" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load1" 1 "sanopt" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load4" 1 "sanopt" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load_n" 1 "sanopt" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store_n" 1 "sanopt" } } */
+/* { dg-final { cleanup-tree-dump "sanopt" } } */
diff --git a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-9.c b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-9.c
index c6575ad..9449de5 100644
--- a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-9.c
+++ b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-9.c
@@ -1,4 +1,4 @@
-/* { dg-options "-fdump-tree-asan0" } */
+/* { dg-options "-fdump-tree-sanopt" } */
 /* { dg-do compile } */
 /* { dg-skip-if "" { *-*-* } { "*" } { "-O0" } } */
 
@@ -9,5 +9,5 @@ f (char *a)
   return  __builtin_strlen (a);
 }
 
-/* { dg-final { scan-tree-dump-times "__asan_report_load1" 1 "asan0" } } */
-/* { dg-final { cleanup-tree-dump "asan0" } } */
+/* { dg-final { scan-tree-dump-times "__asan_report_load1" 1 "sanopt" } } */
+/* { dg-final { cleanup-tree-dump "sanopt" } } */
diff --git a/gcc/tree.c b/gcc/tree.c
index 77e9631..b9f3d60 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -9876,7 +9876,7 @@ local_define_builtin (const char *name, tree type, enum built_in_function code,
 
 /* Call this function after instantiating all builtins that the language
    front end cares about.  This will build the rest of the builtins
-   and internal function that are relied upon by the tree optimizers and
+   and internal functions that are relied upon by the tree optimizers and
    the middle-end.  */
 
 void

^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH 12/17] Fix off-by-one
  2014-10-16  8:35 [PATCH 0/17] KASan 4.9 backport Yury Gribov
                   ` (11 preceding siblings ...)
  2014-10-16  8:41 ` [PATCH 11/17] Move Asan instrumentation to sanopt pass Yury Gribov
@ 2014-10-16  8:41 ` Yury Gribov
  2014-10-16  8:53   ` Jakub Jelinek
  2014-10-16  8:42 ` [PATCH 14/17] Fix test on 32-bit platforms Yury Gribov
                   ` (4 subsequent siblings)
  17 siblings, 1 reply; 49+ messages in thread
From: Yury Gribov @ 2014-10-16  8:41 UTC (permalink / raw)
  To: GCC Patches
  Cc: Jakub Jelinek, Dmitry Vyukov, Konstantin Khlebnikov,
	Andrey Ryabinin, Viacheslav Garbuzov

[-- Attachment #1: Type: text/plain, Size: 18 bytes --]

Same as mainline.

[-- Attachment #2: 0012-2014-10-15-Yury-Gribov-y.gribov-samsung.com.patch --]
[-- Type: text/x-patch, Size: 682 bytes --]

2014-10-15  Yury Gribov  <y.gribov@samsung.com>

	Backport from mainline
	2014-08-12  Yury Gribov  <y.gribov@samsung.com>

	* internal-fn.c (init_internal_fns): Fix off-by-one.

diff --git a/gcc/internal-fn.c b/gcc/internal-fn.c
index 0749dce..d64e20d 100644
--- a/gcc/internal-fn.c
+++ b/gcc/internal-fn.c
@@ -62,7 +62,7 @@ init_internal_fns ()
 {
 #define DEF_INTERNAL_FN(CODE, FLAGS, FNSPEC) \
   if (FNSPEC) internal_fn_fnspec_array[IFN_##CODE] = \
-    build_string ((int) sizeof (FNSPEC) + 1, FNSPEC ? FNSPEC : "");
+    build_string ((int) sizeof (FNSPEC), FNSPEC ? FNSPEC : "");
 #include "internal-fn.def"
 #undef DEF_INTERNAL_FN
   internal_fn_fnspec_array[IFN_LAST] = 0;

^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH 13/17] Fix for PR 62089
  2014-10-16  8:35 [PATCH 0/17] KASan 4.9 backport Yury Gribov
                   ` (9 preceding siblings ...)
  2014-10-16  8:40 ` [PATCH 10/17] Support fnspec for internal fns Yury Gribov
@ 2014-10-16  8:41 ` Yury Gribov
  2014-10-16  8:53   ` Jakub Jelinek
  2014-10-16  8:41 ` [PATCH 11/17] Move Asan instrumentation to sanopt pass Yury Gribov
                   ` (6 subsequent siblings)
  17 siblings, 1 reply; 49+ messages in thread
From: Yury Gribov @ 2014-10-16  8:41 UTC (permalink / raw)
  To: GCC Patches
  Cc: Jakub Jelinek, Dmitry Vyukov, Konstantin Khlebnikov,
	Andrey Ryabinin, Viacheslav Garbuzov

[-- Attachment #1: Type: text/plain, Size: 109 bytes --]

Difference from mainline: replaced non-C-friendly bool with unsigned 
char (see patch 0001 for explanation).

[-- Attachment #2: 0013-2014-10-15-Yury-Gribov-y.gribov-samsung.com.patch --]
[-- Type: text/x-patch, Size: 5302 bytes --]

2014-10-15  Yury Gribov  <y.gribov@samsung.com>

	Backport from mainline
	2014-08-18  Yury Gribov  <y.gribov@samsung.com>

	PR sanitizer/62089

	* asan.c (instrument_derefs): Fix bitfield check.

	* c-c++-common/asan/pr62089.c: New test.
	* c-c++-common/asan/bitfield-1.c: New test.
	* c-c++-common/asan/bitfield-2.c: New test.
	* c-c++-common/asan/bitfield-3.c: New test.
	* c-c++-common/asan/bitfield-4.c: New test.

diff --git a/gcc/asan.c b/gcc/asan.c
index f55b024..e445470 100644
--- a/gcc/asan.c
+++ b/gcc/asan.c
@@ -1688,21 +1688,19 @@ instrument_derefs (gimple_stmt_iterator *iter, tree t,
   int volatilep = 0, unsignedp = 0;
   tree inner = get_inner_reference (t, &bitsize, &bitpos, &offset,
 				    &mode, &unsignedp, &volatilep, false);
-  if (((size_in_bytes & (size_in_bytes - 1)) == 0
-       && (bitpos % (size_in_bytes * BITS_PER_UNIT)))
-      || bitsize != size_in_bytes * BITS_PER_UNIT)
+
+  if (TREE_CODE (t) == COMPONENT_REF
+      && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1)) != NULL_TREE)
     {
-      if (TREE_CODE (t) == COMPONENT_REF
-	  && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1)) != NULL_TREE)
-	{
-	  tree repr = DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1));
-	  instrument_derefs (iter, build3 (COMPONENT_REF, TREE_TYPE (repr),
-					   TREE_OPERAND (t, 0), repr,
-					   NULL_TREE), location, is_store);
-	}
+      tree repr = DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1));
+      instrument_derefs (iter, build3 (COMPONENT_REF, TREE_TYPE (repr),
+				       TREE_OPERAND (t, 0), repr,
+				       NULL_TREE), location, is_store);
       return;
     }
-  if (bitpos % BITS_PER_UNIT)
+
+  if (bitpos % BITS_PER_UNIT
+      || bitsize != size_in_bytes * BITS_PER_UNIT)
     return;
 
   if (TREE_CODE (inner) == VAR_DECL
diff --git a/gcc/testsuite/c-c++-common/asan/bitfield-1.c b/gcc/testsuite/c-c++-common/asan/bitfield-1.c
new file mode 100644
index 0000000..b3f300c
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/asan/bitfield-1.c
@@ -0,0 +1,25 @@
+/* Check that Asan correctly instruments bitfields with non-round size.  */
+
+/* { dg-do run } */
+/* { dg-shouldfail "asan" } */
+
+struct A
+{
+  char base;
+  int : 4;
+  long x : 7;
+};
+
+int __attribute__ ((noinline, noclone))
+f (void *p) {
+  return ((struct A *)p)->x;
+}
+
+int
+main ()
+{
+  char a = 0;
+  return f (&a);
+}
+
+/* { dg-output "ERROR: AddressSanitizer: stack-buffer-overflow" } */
diff --git a/gcc/testsuite/c-c++-common/asan/bitfield-2.c b/gcc/testsuite/c-c++-common/asan/bitfield-2.c
new file mode 100644
index 0000000..8ab0f80
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/asan/bitfield-2.c
@@ -0,0 +1,25 @@
+/* Check that Asan correctly instruments bitfields with non-round offset.  */
+
+/* { dg-do run } */
+/* { dg-shouldfail "asan" } */
+
+struct A
+{
+  char base;
+  int : 7;
+  int x : 8;
+};
+
+int __attribute__ ((noinline, noclone))
+f (void *p) {
+  return ((struct A *)p)->x;
+}
+
+int
+main ()
+{
+  char a = 0;
+  return f (&a);
+}
+
+/* { dg-output "ERROR: AddressSanitizer: stack-buffer-overflow" } */
diff --git a/gcc/testsuite/c-c++-common/asan/bitfield-3.c b/gcc/testsuite/c-c++-common/asan/bitfield-3.c
new file mode 100644
index 0000000..c590778
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/asan/bitfield-3.c
@@ -0,0 +1,25 @@
+/* Check that Asan correctly instruments bitfields with round offset.  */
+
+/* { dg-do run } */
+/* { dg-shouldfail "asan" } */
+
+struct A
+{
+  char base;
+  int : 8;
+  int x : 8;
+};
+
+int __attribute__ ((noinline, noclone))
+f (void *p) {
+  return ((struct A *)p)->x;
+}
+
+int
+main ()
+{
+  char a = 0;
+  return f (&a);
+}
+
+/* { dg-output "ERROR: AddressSanitizer: stack-buffer-overflow" } */
diff --git a/gcc/testsuite/c-c++-common/asan/bitfield-4.c b/gcc/testsuite/c-c++-common/asan/bitfield-4.c
new file mode 100644
index 0000000..94de9a4
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/asan/bitfield-4.c
@@ -0,0 +1,25 @@
+/* Check that Asan correctly instruments bitfields with round offset.  */
+
+/* { dg-do run } */
+/* { dg-shouldfail "asan" } */
+
+struct A
+{
+  char base;
+  int : 0;
+  int x : 8;
+};
+
+int __attribute__ ((noinline, noclone))
+f (void *p) {
+  return ((struct A *)p)->x;
+}
+
+int
+main ()
+{
+  char a = 0;
+  return f (&a);
+}
+
+/* { dg-output "ERROR: AddressSanitizer: stack-buffer-overflow" } */
diff --git a/gcc/testsuite/c-c++-common/asan/pr62089.c b/gcc/testsuite/c-c++-common/asan/pr62089.c
new file mode 100644
index 0000000..6c25ea4
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/asan/pr62089.c
@@ -0,0 +1,41 @@
+/* { dg-do run } */
+/* { dg-shouldfail "asan" } */
+
+#ifndef __cplusplus
+#define bool unsigned char
+#endif
+
+#include <sanitizer/asan_interface.h>
+
+struct vfsmount {};
+struct dentry {};
+
+struct path {
+  struct vfsmount *mnt;
+  struct dentry *dentry;
+};
+
+struct fs_struct {
+  int users;
+  int lock;
+  int seq;
+  int umask;
+  int in_exec;
+  struct path root, pwd;
+};
+
+void __attribute__((noinline, noclone))
+copy_fs_struct(struct fs_struct *a, struct fs_struct *b) {
+  a->root = b->root;
+}
+
+struct fs_struct a, b;
+
+int
+main () {
+  __asan_poison_memory_region (&a.root, sizeof (a.root));
+  copy_fs_struct (&a, &b);
+  return 0;
+}
+
+/* { dg-output "ERROR: AddressSanitizer: use-after-poison" } */

^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH 15/17] Fix for PR 61897 and PR 62140
  2014-10-16  8:35 [PATCH 0/17] KASan 4.9 backport Yury Gribov
                   ` (13 preceding siblings ...)
  2014-10-16  8:42 ` [PATCH 14/17] Fix test on 32-bit platforms Yury Gribov
@ 2014-10-16  8:42 ` Yury Gribov
  2014-10-16  8:54   ` Jakub Jelinek
  2014-10-16  8:43 ` [PATCH 16/17] Disable __asan_init calls for KASan Yury Gribov
                   ` (2 subsequent siblings)
  17 siblings, 1 reply; 49+ messages in thread
From: Yury Gribov @ 2014-10-16  8:42 UTC (permalink / raw)
  To: GCC Patches
  Cc: Jakub Jelinek, Dmitry Vyukov, Konstantin Khlebnikov,
	Andrey Ryabinin, Viacheslav Garbuzov

[-- Attachment #1: Type: text/plain, Size: 18 bytes --]

Same as mainline.

[-- Attachment #2: 0015-2014-10-15-Yury-Gribov-y.gribov-samsung.com.patch --]
[-- Type: text/x-patch, Size: 6190 bytes --]

2014-10-15  Yury Gribov  <y.gribov@samsung.com>

	Backport from mainline
	2014-09-01  Yury Gribov  <y.gribov@samsung.com>

	PR sanitizer/61897
	PR sanitizer/62140

	* asan.c (asan_mem_ref_get_end): Handle non-ptroff_t lengths.
	(build_check_stmt): Likewise.
	(instrument_strlen_call): Likewise.
	(asan_expand_check_ifn): Likewise and fix types.
	(maybe_cast_to_ptrmode): New function.

	* c-c++-common/asan/pr62140-1.c: New test.
	* c-c++-common/asan/pr62140-2.c: New test.

diff --git a/gcc/asan.c b/gcc/asan.c
index e445470..5c6d1c5 100644
--- a/gcc/asan.c
+++ b/gcc/asan.c
@@ -316,6 +316,9 @@ asan_mem_ref_get_end (tree start, tree len)
   if (len == NULL_TREE || integer_zerop (len))
     return start;
 
+  if (!ptrofftype_p (len))
+    len = convert_to_ptrofftype (len);
+
   return fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (start), start, len);
 }
 
@@ -1550,6 +1553,27 @@ maybe_create_ssa_name (location_t loc, tree base, gimple_stmt_iterator *iter,
   return gimple_assign_lhs (g);
 }
 
+/* LEN can already have necessary size and precision;
+   in that case, do not create a new variable.  */
+
+tree
+maybe_cast_to_ptrmode (location_t loc, tree len, gimple_stmt_iterator *iter,
+		       bool before_p)
+{
+  if (ptrofftype_p (len))
+    return len;
+  gimple g
+    = gimple_build_assign_with_ops (NOP_EXPR,
+				    make_ssa_name (pointer_sized_int_node, NULL),
+				    len, NULL);
+  gimple_set_location (g, loc);
+  if (before_p)
+    gsi_insert_before (iter, g, GSI_SAME_STMT);
+  else
+    gsi_insert_after (iter, g, GSI_NEW_STMT);
+  return gimple_assign_lhs (g);
+}
+
 /* Instrument the memory access instruction BASE.  Insert new
    statements before or after ITER.
 
@@ -1595,7 +1619,10 @@ build_check_stmt (location_t loc, tree base, tree len,
   base = maybe_create_ssa_name (loc, base, &gsi, before_p);
 
   if (len)
-    len = unshare_expr (len);
+    {
+      len = unshare_expr (len);
+      len = maybe_cast_to_ptrmode (loc, len, iter, before_p);
+    }
   else
     {
       gcc_assert (size_in_bytes != -1);
@@ -1802,6 +1829,7 @@ instrument_mem_region_access (tree base, tree len,
 static bool
 instrument_strlen_call (gimple_stmt_iterator *iter)
 {
+  gimple g;
   gimple call = gsi_stmt (*iter);
   gcc_assert (is_gimple_call (call));
 
@@ -1810,6 +1838,8 @@ instrument_strlen_call (gimple_stmt_iterator *iter)
 	      && DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL
 	      && DECL_FUNCTION_CODE (callee) == BUILT_IN_STRLEN);
 
+  location_t loc = gimple_location (call);
+
   tree len = gimple_call_lhs (call);
   if (len == NULL)
     /* Some passes might clear the return value of the strlen call;
@@ -1818,28 +1848,28 @@ instrument_strlen_call (gimple_stmt_iterator *iter)
     return false;
   gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (len)));
 
-  location_t loc = gimple_location (call);
+  len = maybe_cast_to_ptrmode (loc, len, iter, /*before_p*/false);
+
   tree str_arg = gimple_call_arg (call, 0);
   bool start_instrumented = has_mem_ref_been_instrumented (str_arg, 1);
 
   tree cptr_type = build_pointer_type (char_type_node);
-  gimple str_arg_ssa =
-    gimple_build_assign_with_ops (NOP_EXPR,
-				  make_ssa_name (cptr_type, NULL),
-				  str_arg, NULL);
-  gimple_set_location (str_arg_ssa, loc);
-  gsi_insert_before (iter, str_arg_ssa, GSI_SAME_STMT);
-
-  build_check_stmt (loc, gimple_assign_lhs (str_arg_ssa), NULL_TREE, 1, iter,
+  g = gimple_build_assign_with_ops (NOP_EXPR,
+				    make_ssa_name (cptr_type, NULL),
+				    str_arg, NULL);
+  gimple_set_location (g, loc);
+  gsi_insert_before (iter, g, GSI_SAME_STMT);
+  str_arg = gimple_assign_lhs (g);
+
+  build_check_stmt (loc, str_arg, NULL_TREE, 1, iter,
 		    /*is_non_zero_len*/true, /*before_p=*/true,
 		    /*is_store=*/false, /*is_scalar_access*/true, /*align*/0,
 		    start_instrumented, start_instrumented);
 
-  gimple g =
-    gimple_build_assign_with_ops (POINTER_PLUS_EXPR,
-				  make_ssa_name (cptr_type, NULL),
-				  gimple_assign_lhs (str_arg_ssa),
-				  len);
+  g = gimple_build_assign_with_ops (POINTER_PLUS_EXPR,
+				    make_ssa_name (cptr_type, NULL),
+				    str_arg,
+				    len);
   gimple_set_location (g, loc);
   gsi_insert_after (iter, g, GSI_NEW_STMT);
 
@@ -2469,9 +2499,6 @@ asan_expand_check_ifn (gimple_stmt_iterator *iter, bool use_calls)
 
   HOST_WIDE_INT real_size_in_bytes = size_in_bytes == -1 ? 1 : size_in_bytes;
 
-  tree uintptr_type
-    = build_nonstandard_integer_type (TYPE_PRECISION (TREE_TYPE (base)), 1);
-
   tree shadow_ptr_type = shadow_ptr_types[real_size_in_bytes == 16 ? 1 : 0];
   tree shadow_type = TREE_TYPE (shadow_ptr_type);
 
@@ -2565,14 +2592,14 @@ asan_expand_check_ifn (gimple_stmt_iterator *iter, bool use_calls)
       if (size_in_bytes == -1 && !end_instrumented)
 	{
 	  g = gimple_build_assign_with_ops (MINUS_EXPR,
-					    make_ssa_name (uintptr_type, NULL),
+					    make_ssa_name (pointer_sized_int_node, NULL),
 					    len,
-					    build_int_cst (uintptr_type, 1));
+					    build_int_cst (pointer_sized_int_node, 1));
 	  gimple_set_location (g, loc);
 	  gsi_insert_after (&gsi, g, GSI_NEW_STMT);
 	  tree last = gimple_assign_lhs (g);
 	  g = gimple_build_assign_with_ops (PLUS_EXPR,
-					    make_ssa_name (uintptr_type, NULL),
+					    make_ssa_name (pointer_sized_int_node, NULL),
 					    base_addr,
 					    last);
 	  gimple_set_location (g, loc);
diff --git a/gcc/testsuite/c-c++-common/asan/pr62140-1.c b/gcc/testsuite/c-c++-common/asan/pr62140-1.c
new file mode 100644
index 0000000..f0b026d
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/asan/pr62140-1.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-w -fpermissive" } */
+
+int memcmp (const void *p, const void *q, int len);
+
+int f (int *p, int *q, int len)
+{
+    return memcmp (p, q, len);
+}
+
diff --git a/gcc/testsuite/c-c++-common/asan/pr62140-2.c b/gcc/testsuite/c-c++-common/asan/pr62140-2.c
new file mode 100644
index 0000000..0bb2563
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/asan/pr62140-2.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-w -fpermissive" } */
+
+int strlen (const char *p);
+
+int f (char *p)
+{
+    int x = strlen (p);
+    return x;
+}
+

^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH 14/17] Fix test on 32-bit platforms
  2014-10-16  8:35 [PATCH 0/17] KASan 4.9 backport Yury Gribov
                   ` (12 preceding siblings ...)
  2014-10-16  8:41 ` [PATCH 12/17] Fix off-by-one Yury Gribov
@ 2014-10-16  8:42 ` Yury Gribov
  2014-10-16  8:54   ` Jakub Jelinek
  2014-10-16  8:42 ` [PATCH 15/17] Fix for PR 61897 and PR 62140 Yury Gribov
                   ` (3 subsequent siblings)
  17 siblings, 1 reply; 49+ messages in thread
From: Yury Gribov @ 2014-10-16  8:42 UTC (permalink / raw)
  To: GCC Patches
  Cc: Jakub Jelinek, Dmitry Vyukov, Konstantin Khlebnikov,
	Andrey Ryabinin, Viacheslav Garbuzov

[-- Attachment #1: Type: text/plain, Size: 18 bytes --]

Same as mainline.

[-- Attachment #2: 0014-2014-10-15-Yury-Gribov-y.gribov-samsung.com.patch --]
[-- Type: text/x-patch, Size: 598 bytes --]

2014-10-15  Yury Gribov  <y.gribov@samsung.com>

	Backport from mainline
	2014-08-28  Yury Gribov  <y.gribov@samsung.com>

	* c-c++-common/asan/pr62089.c: Fix test on 32-bit platforms.

diff --git a/gcc/testsuite/c-c++-common/asan/pr62089.c b/gcc/testsuite/c-c++-common/asan/pr62089.c
index 6c25ea4..48167b1 100644
--- a/gcc/testsuite/c-c++-common/asan/pr62089.c
+++ b/gcc/testsuite/c-c++-common/asan/pr62089.c
@@ -38,4 +38,4 @@ main () {
   return 0;
 }
 
-/* { dg-output "ERROR: AddressSanitizer: use-after-poison" } */
+/* { dg-output "ERROR: AddressSanitizer:\[^\n\r]*on address\[^\n\r]*" } */

^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH 16/17] Disable __asan_init calls for KASan
  2014-10-16  8:35 [PATCH 0/17] KASan 4.9 backport Yury Gribov
                   ` (14 preceding siblings ...)
  2014-10-16  8:42 ` [PATCH 15/17] Fix for PR 61897 and PR 62140 Yury Gribov
@ 2014-10-16  8:43 ` Yury Gribov
  2014-10-16  8:55   ` Jakub Jelinek
  2014-10-16  8:44 ` [PATCH 17/17] Enable __asan_loadN/__asan_storeN " Yury Gribov
  2014-10-17 12:21 ` [PATCH 0/17] KASan 4.9 backport Jakub Jelinek
  17 siblings, 1 reply; 49+ messages in thread
From: Yury Gribov @ 2014-10-16  8:43 UTC (permalink / raw)
  To: GCC Patches
  Cc: Jakub Jelinek, Dmitry Vyukov, Konstantin Khlebnikov,
	Andrey Ryabinin, Viacheslav Garbuzov

[-- Attachment #1: Type: text/plain, Size: 18 bytes --]

Same as mainline.

[-- Attachment #2: 0016-2014-10-15-Yury-Gribov-y.gribov-samsung.com.patch --]
[-- Type: text/x-patch, Size: 1765 bytes --]

2014-10-15  Yury Gribov  <y.gribov@samsung.com>

	Backport from mainline
	2014-10-03  Yury Gribov  <y.gribov@samsung.com>

	* asan.c (asan_finish_file): Disable __asan_init calls for KASan;
	don't emit empty ctors.

diff --git a/gcc/asan.c b/gcc/asan.c
index 5c6d1c5..b8fbed3 100644
--- a/gcc/asan.c
+++ b/gcc/asan.c
@@ -2384,8 +2384,11 @@ asan_finish_file (void)
      nor after .LASAN* array.  */
   flag_sanitize &= ~SANITIZE_ADDRESS;
 
-  tree fn = builtin_decl_implicit (BUILT_IN_ASAN_INIT);
-  append_to_statement_list (build_call_expr (fn, 0), &asan_ctor_statements);
+  if (flag_sanitize & SANITIZE_USER_ADDRESS)
+    {
+      tree fn = builtin_decl_implicit (BUILT_IN_ASAN_INIT);
+      append_to_statement_list (build_call_expr (fn, 0), &asan_ctor_statements);
+    }
   FOR_EACH_DEFINED_VARIABLE (vnode)
     if (TREE_ASM_WRITTEN (vnode->decl)
 	&& asan_protect_global (vnode->decl))
@@ -2422,7 +2425,7 @@ asan_finish_file (void)
       DECL_INITIAL (var) = ctor;
       varpool_assemble_decl (varpool_node_for_decl (var));
 
-      fn = builtin_decl_implicit (BUILT_IN_ASAN_REGISTER_GLOBALS);
+      tree fn = builtin_decl_implicit (BUILT_IN_ASAN_REGISTER_GLOBALS);
       tree gcount_tree = build_int_cst (pointer_sized_int_node, gcount);
       append_to_statement_list (build_call_expr (fn, 2,
 						 build_fold_addr_expr (var),
@@ -2437,8 +2440,9 @@ asan_finish_file (void)
       cgraph_build_static_cdtor ('D', dtor_statements,
 				 MAX_RESERVED_INIT_PRIORITY - 1);
     }
-  cgraph_build_static_cdtor ('I', asan_ctor_statements,
-			     MAX_RESERVED_INIT_PRIORITY - 1);
+  if (asan_ctor_statements)
+    cgraph_build_static_cdtor ('I', asan_ctor_statements,
+			       MAX_RESERVED_INIT_PRIORITY - 1);
   flag_sanitize |= SANITIZE_ADDRESS;
 }

^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH 17/17] Enable __asan_loadN/__asan_storeN for KASan
  2014-10-16  8:35 [PATCH 0/17] KASan 4.9 backport Yury Gribov
                   ` (15 preceding siblings ...)
  2014-10-16  8:43 ` [PATCH 16/17] Disable __asan_init calls for KASan Yury Gribov
@ 2014-10-16  8:44 ` Yury Gribov
  2014-10-16  9:03   ` Jakub Jelinek
  2014-10-17 12:21 ` [PATCH 0/17] KASan 4.9 backport Jakub Jelinek
  17 siblings, 1 reply; 49+ messages in thread
From: Yury Gribov @ 2014-10-16  8:44 UTC (permalink / raw)
  To: GCC Patches
  Cc: Jakub Jelinek, Dmitry Vyukov, Konstantin Khlebnikov,
	Andrey Ryabinin, Viacheslav Garbuzov

[-- Attachment #1: Type: text/plain, Size: 65 bytes --]

Not a backport, specifically enables said instructions in KASan.

[-- Attachment #2: 0017-Instrument-unaligned-objects-in-KASan.patch --]
[-- Type: text/x-patch, Size: 750 bytes --]

Instrument unaligned objects in KASan.

2014-10-15  Yury Gribov  <y.gribov@samsung.com>

	* asan.c (instrument_derefs): Enable unaligned path for KASan.

diff --git a/gcc/asan.c b/gcc/asan.c
index b8fbed3..db4e3a0 100644
--- a/gcc/asan.c
+++ b/gcc/asan.c
@@ -1705,8 +1705,11 @@ instrument_derefs (gimple_stmt_iterator *iter, tree t,
     }
 
   size_in_bytes = int_size_in_bytes (type);
-  if ((size_in_bytes & (size_in_bytes - 1)) != 0
-      || (unsigned HOST_WIDE_INT) size_in_bytes - 1 >= 16)
+  if (size_in_bytes <= 0)
+    return;
+  if ((flag_sanitize & SANITIZE_USER_ADDRESS) != 0
+      && ((size_in_bytes & (size_in_bytes - 1)) != 0
+	  || (unsigned HOST_WIDE_INT) size_in_bytes - 1 >= 16))
     return;
 
   HOST_WIDE_INT bitsize, bitpos;

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 2/17] Introduction of __asan_loadN/__asan_storeN
  2014-10-16  8:37 ` [PATCH 2/17] Introduction of __asan_loadN/__asan_storeN Yury Gribov
@ 2014-10-16  8:44   ` Jakub Jelinek
  0 siblings, 0 replies; 49+ messages in thread
From: Jakub Jelinek @ 2014-10-16  8:44 UTC (permalink / raw)
  To: Yury Gribov
  Cc: GCC Patches, Dmitry Vyukov, Konstantin Khlebnikov,
	Andrey Ryabinin, Viacheslav Garbuzov

On Thu, Oct 16, 2014 at 12:36:15PM +0400, Yury Gribov wrote:
> I disabled __asan_loadN/__asan_storeN because 4.9's Asan runtime doesn't
> support them. In a later patch I re-enable these functions specifically for
> KAsan.

> 2014-10-15  Yury Gribov  <y.gribov@samsung.com>
> 
> 	Backport from mainline
> 	2014-05-30  Jakub Jelinek  <jakub@redhat.com>
> 
> 	* sanitizer.def (BUILT_IN_ASAN_REPORT_LOAD_N,
> 	BUILT_IN_ASAN_REPORT_STORE_N): New.
> 	* asan.c (struct asan_mem_ref): Change access_size type to
> 	HOST_WIDE_INT.
> 	(asan_mem_ref_init, asan_mem_ref_new, get_mem_refs_of_builtin_call,
> 	update_mem_ref_hash_table): Likewise.
> 	(asan_mem_ref_hasher::hash): Hash in a HWI.
> 	(report_error_func): Change size_in_bytes argument to HWI.
> 	Use *_N builtins if size_in_bytes is larger than 16 or not power of
> 	two.
> 	(build_shadow_mem_access): New function.
> 	(build_check_stmt): Use it.  Change size_in_bytes argument to HWI.
> 	Handle size_in_bytes not power of two or larger than 16.
> 	(instrument_derefs): Don't give up if size_in_bytes is not
> 	power of two or is larger than 16.

Ok.

	Jakub

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 3/17] Instrumentation of unaligned types
  2014-10-16  8:36 ` [PATCH 3/17] Instrumentation of unaligned types Yury Gribov
@ 2014-10-16  8:45   ` Jakub Jelinek
  0 siblings, 0 replies; 49+ messages in thread
From: Jakub Jelinek @ 2014-10-16  8:45 UTC (permalink / raw)
  To: Yury Gribov
  Cc: GCC Patches, Dmitry Vyukov, Konstantin Khlebnikov,
	Andrey Ryabinin, Viacheslav Garbuzov

On Thu, Oct 16, 2014 at 12:36:37PM +0400, Yury Gribov wrote:
> Further work on __asan_loadN/__asan_storeN. I removed the tests
> (misalign-1.c, misalign-2.c) because (as mentioned in comments for
> preceeding patch) __asan_loadN/__asan_storeN are disabled for userspace.

> 2014-10-15  Yury Gribov  <y.gribov@samsung.com>
> 
> 	Backport from mainline
>  	2014-05-30  Jakub Jelinek  <jakub@redhat.com>
> 
> 	* asan.c (report_error_func): Add SLOW_P argument, use
> 	BUILT_IN_ASAN_*_N if set.
> 	(build_check_stmt): Likewise.
> 	(instrument_derefs): If T has insufficient alignment,
> 	force same handling as for odd sizes.

Ok.

	Jakub

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 4/17] Outline instrumentation
  2014-10-16  8:37 ` [PATCH 4/17] Outline instrumentation Yury Gribov
@ 2014-10-16  8:46   ` Jakub Jelinek
  0 siblings, 0 replies; 49+ messages in thread
From: Jakub Jelinek @ 2014-10-16  8:46 UTC (permalink / raw)
  To: Yury Gribov
  Cc: GCC Patches, Dmitry Vyukov, Konstantin Khlebnikov,
	Andrey Ryabinin, Viacheslav Garbuzov

On Thu, Oct 16, 2014 at 12:37:37PM +0400, Yury Gribov wrote:
> 4.9's Asan runtime library provides no support for these so I removed the
> tests. I've also changed default value of threshold to INT_MAX to completely
> disable outline instrumentation in userspace Asan.

> New asan-instrumentation-with-call-threshold parameter.
> 
> 2014-10-15  Yury Gribov  <y.gribov@samsung.com>
> 
> 	Backport from mainline
> 	2014-06-16  Yury Gribov  <y.gribov@samsung.com>
> 
> 	* asan.c (check_func): New function.
> 	(maybe_create_ssa_name): Likewise.
> 	(build_check_stmt_with_calls): Likewise.
> 	(use_calls_p): Likewise.
> 	(report_error_func): Change interface.
> 	(build_check_stmt): Allow non-integer lengths; add support
> 	for new parameter.
> 	(asan_instrument): Likewise.
> 	(instrument_mem_region_access): Moved code to
> 	build_check_stmt.
> 	(instrument_derefs): Likewise.
> 	(instrument_strlen_call): Likewise.
> 	* cfgcleanup.c (old_insns_match_p): Add support for new
> 	functions.
> 	* doc/invoke.texi: Describe new parameter.
> 	* params.def: Define new parameter.
> 	* params.h: Likewise.
> 	* sanitizer.def: Describe new builtins.
> 
> 	* c-c++-common/asan/instrument-with-calls-1.c: New test.
> 	* c-c++-common/asan/instrument-with-calls-2.c: Likewise.
> 	* c-c++-common/asan/no-redundant-instrumentation-1.c: Update
> 	test patterns.
> 	* c-c++-common/asan/no-redundant-instrumentation-2.c:
> 	Likewise.
> 	* c-c++-common/asan/no-redundant-instrumentation-4.c:
> 	Likewise.
> 	* c-c++-common/asan/no-redundant-instrumentation-5.c:
> 	Likewise.
> 	* c-c++-common/asan/no-redundant-instrumentation-6.c:
> 	Likewise.
> 	* c-c++-common/asan/no-redundant-instrumentation-7.c:
> 	Likewise.
> 	* c-c++-common/asan/no-redundant-instrumentation-8.c:
> 	Likewise.

Ok.

	Jakub

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 5/17] Fix bootstrap error
  2014-10-16  8:38 ` [PATCH 5/17] Fix bootstrap error Yury Gribov
@ 2014-10-16  8:47   ` Jakub Jelinek
  0 siblings, 0 replies; 49+ messages in thread
From: Jakub Jelinek @ 2014-10-16  8:47 UTC (permalink / raw)
  To: Yury Gribov
  Cc: GCC Patches, Dmitry Vyukov, Konstantin Khlebnikov,
	Andrey Ryabinin, Viacheslav Garbuzov

On Thu, Oct 16, 2014 at 12:38:00PM +0400, Yury Gribov wrote:
> Same as mainline.

> 2014-10-15  Yury Gribov  <y.gribov@samsung.com>
> 
> 	Backport from mainline
> 	2014-06-16  Yury Gribov  <y.gribov@samsung.com>
> 
> 	* asan.c (build_check_stmt): Fix maybe-uninitialized warning.

Ok.

	Jakub

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 6/17] Fix for PR 61530
  2014-10-16  8:38 ` [PATCH 6/17] Fix for PR 61530 Yury Gribov
@ 2014-10-16  8:47   ` Jakub Jelinek
  0 siblings, 0 replies; 49+ messages in thread
From: Jakub Jelinek @ 2014-10-16  8:47 UTC (permalink / raw)
  To: Yury Gribov
  Cc: GCC Patches, Dmitry Vyukov, Konstantin Khlebnikov,
	Andrey Ryabinin, Viacheslav Garbuzov

On Thu, Oct 16, 2014 at 12:38:19PM +0400, Yury Gribov wrote:
> Same as mainline.

> 2014-10-15  Yury Gribov  <y.gribov@samsung.com>
> 
> 	Backport from mainline
> 	2014-06-18  Yury Gribov  <y.gribov@samsung.com>
> 
> 	PR sanitizer/61530
> 
> 	* asan.c (build_check_stmt): Add condition.
> 
> 	* c-c++-common/asan/pr61530.c: New test.

Ok.  Note, for the patches that fix bugs in earlier patches,
please commit them in one svn revision together with the patch
that caused the bugs, so that 4.9 isn't broken unnecessarily.

	Jakub

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 7/17] Fix for PR 61547
  2014-10-16  8:39 ` [PATCH 7/17] Fix for PR 61547 Yury Gribov
@ 2014-10-16  8:49   ` Jakub Jelinek
  0 siblings, 0 replies; 49+ messages in thread
From: Jakub Jelinek @ 2014-10-16  8:49 UTC (permalink / raw)
  To: Yury Gribov
  Cc: GCC Patches, Dmitry Vyukov, Konstantin Khlebnikov,
	Andrey Ryabinin, Viacheslav Garbuzov

On Thu, Oct 16, 2014 at 12:38:51PM +0400, Yury Gribov wrote:
> Difference from mainline: replaced non-C-friendly bool with unsigned char
> (see patch 0001 for explanation).

> 2014-10-15  Yury Gribov  <y.gribov@samsung.com>
> 
> 	Backport from mainline
> 	2014-06-18  Yury Gribov  <y.gribov@samsung.com>
> 
> 	PR sanitizer/61547
> 
> 	* asan.c (instrument_strlen_call): Fixed instrumentation of
> 	trailing byte.
> 
> 	* c-c++-common/asan/strlen-overflow-1.c: New test.

Ok.

	Jakub

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 8/17] Optimization of strlen instrumentation
  2014-10-16  8:39 ` [PATCH 8/17] Optimization of strlen instrumentation Yury Gribov
@ 2014-10-16  8:50   ` Jakub Jelinek
  2014-10-16  9:06     ` Yury Gribov
  0 siblings, 1 reply; 49+ messages in thread
From: Jakub Jelinek @ 2014-10-16  8:50 UTC (permalink / raw)
  To: Yury Gribov
  Cc: GCC Patches, Dmitry Vyukov, Konstantin Khlebnikov,
	Andrey Ryabinin, Viacheslav Garbuzov

On Thu, Oct 16, 2014 at 12:39:17PM +0400, Yury Gribov wrote:
> Difference from mainline: replaced non-C-friendly bool with unsigned char
> (see patch 0001 for explanation).

Where?  I don't see unsigned char being used anywhere in the patch.
bool is certainly fine in GCC itself.

> Do not instrument first byte in strlen if already instrumented.
> 
> 2014-10-15  Yury Gribov  <y.gribov@samsung.com>
> 
> 	Backport from mainline
> 	2014-06-24  Max Ostapenko  <m.ostapenko@partner.samsung.com>
> 
> 	* asan.c (instrument_strlen_call): Do not instrument first byte in strlen
> 	if already instrumented.
> 
> 	* c-c++-common/asan/no-redundant-instrumentation-9.c: New test.

Ok.

	Jakub

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 9/17] Initial KAsan support
  2014-10-16  8:40 ` [PATCH 9/17] Initial KAsan support Yury Gribov
@ 2014-10-16  8:51   ` Jakub Jelinek
  2014-10-17  7:29   ` Eric Botcazou
  1 sibling, 0 replies; 49+ messages in thread
From: Jakub Jelinek @ 2014-10-16  8:51 UTC (permalink / raw)
  To: Yury Gribov
  Cc: GCC Patches, Dmitry Vyukov, Konstantin Khlebnikov,
	Andrey Ryabinin, Viacheslav Garbuzov

On Thu, Oct 16, 2014 at 12:39:56PM +0400, Yury Gribov wrote:
> The patch was slightly updated to take care of missing UBSan work
> (SANITIZE_FLOAT_DIVIDE, SANITIZE_FLOAT_CAST, SANITIZE_BOUNDS).

> 2014-10-15  Yury Gribov  <y.gribov@samsung.com>
> 
> 	Backport from mainline
> 	2014-07-31  Yury Gribov  <y.gribov@samsung.com>
> 
> 	* doc/cpp.texi (__SANITIZE_ADDRESS__): Updated description.
> 	* doc/invoke.texi (-fsanitize=kernel-address): Describe new option.
> 	* flag-types.h (SANITIZE_USER_ADDRESS, SANITIZE_KERNEL_ADDRESS):
> 	New enums.
> 	* gcc.c (sanitize_spec_function): Support new option.
> 	(SANITIZER_SPEC): Remove now redundant check.
> 	* opts.c (common_handle_option): Support new option.
> 	(finish_options): Check for incompatibilities.
> 	* toplev.c (process_options): Split userspace-specific checks.

Ok.

	Jakub

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 11/17] Move Asan instrumentation to sanopt pass
  2014-10-16  8:41 ` [PATCH 11/17] Move Asan instrumentation to sanopt pass Yury Gribov
@ 2014-10-16  8:52   ` Jakub Jelinek
  0 siblings, 0 replies; 49+ messages in thread
From: Jakub Jelinek @ 2014-10-16  8:52 UTC (permalink / raw)
  To: Yury Gribov
  Cc: GCC Patches, Dmitry Vyukov, Konstantin Khlebnikov,
	Andrey Ryabinin, Viacheslav Garbuzov

On Thu, Oct 16, 2014 at 12:40:44PM +0400, Yury Gribov wrote:
> The patch was slightly updated to take care of missing UBSan work
> (UBSAN_BOUNDS).

> Move inlining of Asan memory checks to sanopt pass.
> Change asan-instrumentation-with-call-threshold to more closely match LLVM.
> 
> 2014-10-15  Yury Gribov  <y.gribov@samsung.com>
> 
> 	Backport from mainline
> 	2014-08-11  Yury Gribov  <y.gribov@samsung.com>
> 
> 	* asan.c (asan_check_flags): New enum.
> 	(build_check_stmt_with_calls): Removed function.
> 	(build_check_stmt): Split inlining logic to
> 	asan_expand_check_ifn.
> 	(instrument_derefs): Rename parameter.
> 	(instrument_mem_region_access): Rename parameter.
> 	(instrument_strlen_call): Likewise.
> 	(asan_expand_check_ifn): New function.
> 	(asan_instrument): Remove old code.
> 	(pass_sanopt::execute): Change handling of
> 	asan-instrumentation-with-call-threshold.
> 	(asan_clear_shadow): Fix formatting.
> 	(asan_function_start): Likewise.
> 	(asan_emit_stack_protection): Likewise.
> 	* doc/invoke.texi (asan-instrumentation-with-call-threshold):
> 	Update description.
> 	* internal-fn.c (expand_ASAN_CHECK): New function.
> 	* internal-fn.def (ASAN_CHECK): New internal function.
> 	* params.def (PARAM_ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD):
> 	Update description.
> 	(PARAM_ASAN_USE_AFTER_RETURN): Likewise.
> 	* tree.c: Small comment fix.
> 
> 	* c-c++-common/asan/inc.c: Update test.
> 	* c-c++-common/asan/instrument-with-calls-2.c: Likewise.
> 	* c-c++-common/asan/no-redundant-instrumentation-1.c: Likewise.
> 	* c-c++-common/asan/no-redundant-instrumentation-2.c: Likewise.
> 	* c-c++-common/asan/no-redundant-instrumentation-3.c: Likewise.
> 	* c-c++-common/asan/no-redundant-instrumentation-4.c: Likewise.
> 	* c-c++-common/asan/no-redundant-instrumentation-5.c: Likewise.
> 	* c-c++-common/asan/no-redundant-instrumentation-6.c: Likewise.
> 	* c-c++-common/asan/no-redundant-instrumentation-7.c: Likewise.
> 	* c-c++-common/asan/no-redundant-instrumentation-8.c: Likewise.
> 	* c-c++-common/asan/no-redundant-instrumentation-9.c: Likewise.

Ok.

	Jakub

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 10/17] Support fnspec for internal fns
  2014-10-16  8:40 ` [PATCH 10/17] Support fnspec for internal fns Yury Gribov
@ 2014-10-16  8:52   ` Jakub Jelinek
  0 siblings, 0 replies; 49+ messages in thread
From: Jakub Jelinek @ 2014-10-16  8:52 UTC (permalink / raw)
  To: Yury Gribov
  Cc: GCC Patches, Dmitry Vyukov, Konstantin Khlebnikov,
	Andrey Ryabinin, Viacheslav Garbuzov

On Thu, Oct 16, 2014 at 12:40:17PM +0400, Yury Gribov wrote:
> The patch was slightly updated to take care of missing UBSan work
> (UBSAN_BOUNDS).

> Added fnspec to internal functions.
> 
> 2014-10-15  Yury Gribov  <y.gribov@samsung.com>
> 
> 	Backport from mainline
> 	2014-08-11  Yury Gribov  <y.gribov@samsung.com>
> 
>         * gimple.c (gimple_call_fnspec): Support internal functions.
>         (gimple_call_return_flags): Use const.
>         * Makefile.in (GTFILES): Add internal-fn.h to list of GC files.
>         * internal-fn.def: Add fnspec information.
>         * internal-fn.h (internal_fn_fnspec): New function.
>         (init_internal_fns): Declare new function.
>         * internal-fn.c (internal_fn_fnspec_array): New global variable.
>         (init_internal_fns): New function.
>         * tree-core.h: Update macro call.
>         * tree.c (build_common_builtin_nodes): Initialize internal fns.

Ok.

	Jakub

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 13/17] Fix for PR 62089
  2014-10-16  8:41 ` [PATCH 13/17] Fix for PR 62089 Yury Gribov
@ 2014-10-16  8:53   ` Jakub Jelinek
  0 siblings, 0 replies; 49+ messages in thread
From: Jakub Jelinek @ 2014-10-16  8:53 UTC (permalink / raw)
  To: Yury Gribov
  Cc: GCC Patches, Dmitry Vyukov, Konstantin Khlebnikov,
	Andrey Ryabinin, Viacheslav Garbuzov

On Thu, Oct 16, 2014 at 12:41:24PM +0400, Yury Gribov wrote:
> Difference from mainline: replaced non-C-friendly bool with unsigned char
> (see patch 0001 for explanation).

> 2014-10-15  Yury Gribov  <y.gribov@samsung.com>
> 
> 	Backport from mainline
> 	2014-08-18  Yury Gribov  <y.gribov@samsung.com>
> 
> 	PR sanitizer/62089
> 
> 	* asan.c (instrument_derefs): Fix bitfield check.
> 
> 	* c-c++-common/asan/pr62089.c: New test.
> 	* c-c++-common/asan/bitfield-1.c: New test.
> 	* c-c++-common/asan/bitfield-2.c: New test.
> 	* c-c++-common/asan/bitfield-3.c: New test.
> 	* c-c++-common/asan/bitfield-4.c: New test.

Ok.

	Jakub

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 12/17] Fix off-by-one
  2014-10-16  8:41 ` [PATCH 12/17] Fix off-by-one Yury Gribov
@ 2014-10-16  8:53   ` Jakub Jelinek
  0 siblings, 0 replies; 49+ messages in thread
From: Jakub Jelinek @ 2014-10-16  8:53 UTC (permalink / raw)
  To: Yury Gribov
  Cc: GCC Patches, Dmitry Vyukov, Konstantin Khlebnikov,
	Andrey Ryabinin, Viacheslav Garbuzov

On Thu, Oct 16, 2014 at 12:41:03PM +0400, Yury Gribov wrote:
> Same as mainline.

> 2014-10-15  Yury Gribov  <y.gribov@samsung.com>
> 
> 	Backport from mainline
> 	2014-08-12  Yury Gribov  <y.gribov@samsung.com>
> 
> 	* internal-fn.c (init_internal_fns): Fix off-by-one.

Ok.

	Jakub

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 15/17] Fix for PR 61897 and PR 62140
  2014-10-16  8:42 ` [PATCH 15/17] Fix for PR 61897 and PR 62140 Yury Gribov
@ 2014-10-16  8:54   ` Jakub Jelinek
  0 siblings, 0 replies; 49+ messages in thread
From: Jakub Jelinek @ 2014-10-16  8:54 UTC (permalink / raw)
  To: Yury Gribov
  Cc: GCC Patches, Dmitry Vyukov, Konstantin Khlebnikov,
	Andrey Ryabinin, Viacheslav Garbuzov

On Thu, Oct 16, 2014 at 12:42:09PM +0400, Yury Gribov wrote:
> Same as mainline.

> 2014-10-15  Yury Gribov  <y.gribov@samsung.com>
> 
> 	Backport from mainline
> 	2014-09-01  Yury Gribov  <y.gribov@samsung.com>
> 
> 	PR sanitizer/61897
> 	PR sanitizer/62140
> 
> 	* asan.c (asan_mem_ref_get_end): Handle non-ptroff_t lengths.
> 	(build_check_stmt): Likewise.
> 	(instrument_strlen_call): Likewise.
> 	(asan_expand_check_ifn): Likewise and fix types.
> 	(maybe_cast_to_ptrmode): New function.
> 
> 	* c-c++-common/asan/pr62140-1.c: New test.
> 	* c-c++-common/asan/pr62140-2.c: New test.

Ok.

	Jakub

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 14/17] Fix test on 32-bit platforms
  2014-10-16  8:42 ` [PATCH 14/17] Fix test on 32-bit platforms Yury Gribov
@ 2014-10-16  8:54   ` Jakub Jelinek
  0 siblings, 0 replies; 49+ messages in thread
From: Jakub Jelinek @ 2014-10-16  8:54 UTC (permalink / raw)
  To: Yury Gribov
  Cc: GCC Patches, Dmitry Vyukov, Konstantin Khlebnikov,
	Andrey Ryabinin, Viacheslav Garbuzov

On Thu, Oct 16, 2014 at 12:41:46PM +0400, Yury Gribov wrote:
> Same as mainline.

> 2014-10-15  Yury Gribov  <y.gribov@samsung.com>
> 
> 	Backport from mainline
> 	2014-08-28  Yury Gribov  <y.gribov@samsung.com>
> 
> 	* c-c++-common/asan/pr62089.c: Fix test on 32-bit platforms.

Ok.

	Jakub

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 16/17] Disable __asan_init calls for KASan
  2014-10-16  8:43 ` [PATCH 16/17] Disable __asan_init calls for KASan Yury Gribov
@ 2014-10-16  8:55   ` Jakub Jelinek
  0 siblings, 0 replies; 49+ messages in thread
From: Jakub Jelinek @ 2014-10-16  8:55 UTC (permalink / raw)
  To: Yury Gribov
  Cc: GCC Patches, Dmitry Vyukov, Konstantin Khlebnikov,
	Andrey Ryabinin, Viacheslav Garbuzov

On Thu, Oct 16, 2014 at 12:42:28PM +0400, Yury Gribov wrote:
> Same as mainline.

> 2014-10-15  Yury Gribov  <y.gribov@samsung.com>
> 
> 	Backport from mainline
> 	2014-10-03  Yury Gribov  <y.gribov@samsung.com>
> 
> 	* asan.c (asan_finish_file): Disable __asan_init calls for KASan;
> 	don't emit empty ctors.

Ok.

	Jakub

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 17/17] Enable __asan_loadN/__asan_storeN for KASan
  2014-10-16  8:44 ` [PATCH 17/17] Enable __asan_loadN/__asan_storeN " Yury Gribov
@ 2014-10-16  9:03   ` Jakub Jelinek
  0 siblings, 0 replies; 49+ messages in thread
From: Jakub Jelinek @ 2014-10-16  9:03 UTC (permalink / raw)
  To: Yury Gribov
  Cc: GCC Patches, Dmitry Vyukov, Konstantin Khlebnikov,
	Andrey Ryabinin, Viacheslav Garbuzov

On Thu, Oct 16, 2014 at 12:43:25PM +0400, Yury Gribov wrote:
> Not a backport, specifically enables said instructions in KASan.

> Instrument unaligned objects in KASan.
> 
> 2014-10-15  Yury Gribov  <y.gribov@samsung.com>
> 
> 	* asan.c (instrument_derefs): Enable unaligned path for KASan.
> 
> diff --git a/gcc/asan.c b/gcc/asan.c
> index b8fbed3..db4e3a0 100644
> --- a/gcc/asan.c
> +++ b/gcc/asan.c
> @@ -1705,8 +1705,11 @@ instrument_derefs (gimple_stmt_iterator *iter, tree t,
>      }
>  
>    size_in_bytes = int_size_in_bytes (type);
> -  if ((size_in_bytes & (size_in_bytes - 1)) != 0
> -      || (unsigned HOST_WIDE_INT) size_in_bytes - 1 >= 16)
> +  if (size_in_bytes <= 0)
> +    return;
> +  if ((flag_sanitize & SANITIZE_USER_ADDRESS) != 0
> +      && ((size_in_bytes & (size_in_bytes - 1)) != 0
> +	  || (unsigned HOST_WIDE_INT) size_in_bytes - 1 >= 16))
>      return;
>  
>    HOST_WIDE_INT bitsize, bitpos;

Ok.

	Jakub

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 8/17] Optimization of strlen instrumentation
  2014-10-16  8:50   ` Jakub Jelinek
@ 2014-10-16  9:06     ` Yury Gribov
  0 siblings, 0 replies; 49+ messages in thread
From: Yury Gribov @ 2014-10-16  9:06 UTC (permalink / raw)
  To: Jakub Jelinek
  Cc: GCC Patches, Dmitry Vyukov, Konstantin Khlebnikov,
	Andrey Ryabinin, Viacheslav Garbuzov

On 10/16/2014 12:49 PM, Jakub Jelinek wrote:
> On Thu, Oct 16, 2014 at 12:39:17PM +0400, Yury Gribov wrote:
>> Difference from mainline: replaced non-C-friendly bool with unsigned char
>> (see patch 0001 for explanation).
>
> Where?  I don't see unsigned char being used anywhere in the patch.
> bool is certainly fine in GCC itself.

Probably slipped from a neighbor patch :/ In summary all patches that 
have #include "asan_interface.h" have this quirk which I'll try to 
replace with #include "stdbool.h" per your suggestion.

-Y

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 9/17] Initial KAsan support
  2014-10-16  8:40 ` [PATCH 9/17] Initial KAsan support Yury Gribov
  2014-10-16  8:51   ` Jakub Jelinek
@ 2014-10-17  7:29   ` Eric Botcazou
  2014-10-17  7:44     ` Yury Gribov
  1 sibling, 1 reply; 49+ messages in thread
From: Eric Botcazou @ 2014-10-17  7:29 UTC (permalink / raw)
  To: Yury Gribov
  Cc: Dmitry Vyukov, gcc-patches, Jakub Jelinek, Konstantin Khlebnikov,
	Andrey Ryabinin, Viacheslav Garbuzov

> The patch was slightly updated to take care of missing UBSan work
> (SANITIZE_FLOAT_DIVIDE, SANITIZE_FLOAT_CAST, SANITIZE_BOUNDS).

--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -868,6 +868,20 @@ finish_options (struct gcc_options *opts, struct 
gcc_options *opts_set,
   /* The -gsplit-dwarf option requires -gpubnames.  */
   if (opts->x_dwarf_split_debug_info)
     opts->x_debug_generate_pub_sections = 1;
+
+  /* Userspace and kernel ASan conflict with each other and with TSan.  */
+
+  if ((flag_sanitize & SANITIZE_USER_ADDRESS)
+      && (flag_sanitize & SANITIZE_KERNEL_ADDRESS))
+    error_at (loc,
+              "-fsanitize=address is incompatible with "
+              "-fsanitize=kernel-address");
+
+  if ((flag_sanitize & SANITIZE_ADDRESS)
+      && (flag_sanitize & SANITIZE_THREAD))
+    error_at (loc,
+              "-fsanitize=address and -fsanitize=kernel-address "
+              "are incompatible with -fsanitize=thread");
 }

Why aren't you using opts->x_ here, like all the code just above?

-- 
Eric Botcazou

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 9/17] Initial KAsan support
  2014-10-17  7:29   ` Eric Botcazou
@ 2014-10-17  7:44     ` Yury Gribov
  2014-10-17  7:49       ` Eric Botcazou
  0 siblings, 1 reply; 49+ messages in thread
From: Yury Gribov @ 2014-10-17  7:44 UTC (permalink / raw)
  To: Eric Botcazou
  Cc: Dmitry Vyukov, gcc-patches, Jakub Jelinek, Konstantin Khlebnikov,
	Andrey Ryabinin, Viacheslav Garbuzov

On 10/17/2014 11:27 AM, Eric Botcazou wrote:
>> The patch was slightly updated to take care of missing UBSan work
>> (SANITIZE_FLOAT_DIVIDE, SANITIZE_FLOAT_CAST, SANITIZE_BOUNDS).
>
> --- a/gcc/opts.c
> +++ b/gcc/opts.c
> @@ -868,6 +868,20 @@ finish_options (struct gcc_options *opts, struct
> gcc_options *opts_set,
>     /* The -gsplit-dwarf option requires -gpubnames.  */
>     if (opts->x_dwarf_split_debug_info)
>       opts->x_debug_generate_pub_sections = 1;
> +
> +  /* Userspace and kernel ASan conflict with each other and with TSan.  */
> +
> +  if ((flag_sanitize & SANITIZE_USER_ADDRESS)
> +      && (flag_sanitize & SANITIZE_KERNEL_ADDRESS))
> +    error_at (loc,
> +              "-fsanitize=address is incompatible with "
> +              "-fsanitize=kernel-address");
> +
> +  if ((flag_sanitize & SANITIZE_ADDRESS)
> +      && (flag_sanitize & SANITIZE_THREAD))
> +    error_at (loc,
> +              "-fsanitize=address and -fsanitize=kernel-address "
> +              "are incompatible with -fsanitize=thread");
>   }
>
> Why aren't you using opts->x_ here, like all the code just above?

Well, that's a backport of ancient patch from trunk so all credits go 
there. And flag_sanitize is indeed handled differently from other 
compiler flags.

-Y

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 9/17] Initial KAsan support
  2014-10-17  7:44     ` Yury Gribov
@ 2014-10-17  7:49       ` Eric Botcazou
  2014-10-17  8:45         ` Yury Gribov
  0 siblings, 1 reply; 49+ messages in thread
From: Eric Botcazou @ 2014-10-17  7:49 UTC (permalink / raw)
  To: Yury Gribov
  Cc: gcc-patches, Dmitry Vyukov, Jakub Jelinek, Konstantin Khlebnikov,
	Andrey Ryabinin, Viacheslav Garbuzov

> Well, that's a backport of ancient patch from trunk so all credits go
> there. And flag_sanitize is indeed handled differently from other
> compiler flags.

Really curious to know why...

-- 
Eric Botcazou

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 9/17] Initial KAsan support
  2014-10-17  7:49       ` Eric Botcazou
@ 2014-10-17  8:45         ` Yury Gribov
  2014-10-17 12:04           ` Jakub Jelinek
  0 siblings, 1 reply; 49+ messages in thread
From: Yury Gribov @ 2014-10-17  8:45 UTC (permalink / raw)
  To: Eric Botcazou
  Cc: gcc-patches, Dmitry Vyukov, Jakub Jelinek, Konstantin Khlebnikov,
	Andrey Ryabinin, Viacheslav Garbuzov

On 10/17/2014 11:43 AM, Eric Botcazou wrote:
>> Well, that's a backport of ancient patch from trunk so all credits go
>> there. And flag_sanitize is indeed handled differently from other
>> compiler flags.
>
> Really curious to know why...

I bet this was a typo but let's wait for Jakub's comments.

-Y

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 9/17] Initial KAsan support
  2014-10-17  8:45         ` Yury Gribov
@ 2014-10-17 12:04           ` Jakub Jelinek
  0 siblings, 0 replies; 49+ messages in thread
From: Jakub Jelinek @ 2014-10-17 12:04 UTC (permalink / raw)
  To: Yury Gribov
  Cc: Eric Botcazou, gcc-patches, Dmitry Vyukov, Konstantin Khlebnikov,
	Andrey Ryabinin, Viacheslav Garbuzov

On Fri, Oct 17, 2014 at 12:44:26PM +0400, Yury Gribov wrote:
> On 10/17/2014 11:43 AM, Eric Botcazou wrote:
> >>Well, that's a backport of ancient patch from trunk so all credits go
> >>there. And flag_sanitize is indeed handled differently from other
> >>compiler flags.
> >
> >Really curious to know why...
> 
> I bet this was a typo but let's wait for Jakub's comments.

The obvious change to replace the direct flag with opts->x_ preapproved.

	Jakub

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 0/17] KASan 4.9 backport
  2014-10-16  8:35 [PATCH 0/17] KASan 4.9 backport Yury Gribov
                   ` (16 preceding siblings ...)
  2014-10-16  8:44 ` [PATCH 17/17] Enable __asan_loadN/__asan_storeN " Yury Gribov
@ 2014-10-17 12:21 ` Jakub Jelinek
  2014-10-17 13:49   ` Yury Gribov
  17 siblings, 1 reply; 49+ messages in thread
From: Jakub Jelinek @ 2014-10-17 12:21 UTC (permalink / raw)
  To: Yury Gribov
  Cc: GCC Patches, Dmitry Vyukov, Konstantin Khlebnikov,
	Andrey Ryabinin, Viacheslav Garbuzov

On Thu, Oct 16, 2014 at 12:34:35PM +0400, Yury Gribov wrote:
> Hi all,
> 
> As discussed in https://gcc.gnu.org/ml/gcc/2014-09/msg00234.html , this
> patchset backports mainline patches necessary for Kernel ASan in GCC 4.9
> (gcc-4_9-branch). The patcheset consists of
> * Asan headers installation (1 patch)
> * __asan_loadN/__asan_storeN support (3 patches)
> * instrumentation with calls support (1 patch)
> * optimization of strlen instrumentation (1 patch)
> * Kasan support (3 patches)
> * move inlining to sanopt (1 patches)
> * bugfixes (7 patches)
> 
> To my knowledge it does not contain any changes that would influence ABI of
> generated code.
> 
> The code was bootstrapped and regtested on x64 (I only tested the net
> result, not each patch in isolation).

I had a brief look at what ended up on the branch in the end, and
from what I understand, the 4.9 libasan.so has
__asan_report_store_n and __asan_report_load_n entry points, but does
not have any __asan_loadN/__asan_reportN entrypoints (neither 1/2/4/8/16,
nor variable).
So, what the branch does seems to not match what the library provides.
E.g. trying:
struct S { long long a; long long b; char c; };

void
foo (struct S *p, struct S *q)
{
  *p = *q;
}

int
bar (struct S *p)
{
  return p->a;
}

on x86_64-linux, with -fsanitize=kernel-address -O2 I get expected
__asan_storeN/__asan_loadN/__asan_load8 calls.
With -fsanitize=address -O2, foo unexpectedly is not instrumented
(IMHO it should be, it can use __asan_report_{store,load}_n) and
bar uses (expectedly) __asan_report_load8.
With -fsanitize=address -O2 --param asan-instrumentation-with-call-threshold=0
foo is again unexpectedly not instrumented, and bar is instrumented
with __asan_load8, which looks wrong to me, because the library does not
provide any such entry point.

Thus, IMHO the:
  if ((flag_sanitize & SANITIZE_USER_ADDRESS) != 0
      && ((size_in_bytes & (size_in_bytes - 1)) != 0
	  || (unsigned HOST_WIDE_INT) size_in_bytes - 1 >= 16))
    return;
should be nuked from 4.9, we can do unaligned/non-{1,2,4,8,16}
accesses fine.  But, in execute_sanopt force !use_calls
for (flag_sanitize & SANITIZE_USER_ADDRESS).

Or were there any bugfixes needed for __asan_report_{store,load}_n
on the library side?

	Jakub

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 0/17] KASan 4.9 backport
  2014-10-17 12:21 ` [PATCH 0/17] KASan 4.9 backport Jakub Jelinek
@ 2014-10-17 13:49   ` Yury Gribov
  2014-10-17 14:02     ` Jakub Jelinek
  0 siblings, 1 reply; 49+ messages in thread
From: Yury Gribov @ 2014-10-17 13:49 UTC (permalink / raw)
  To: Jakub Jelinek
  Cc: GCC Patches, Dmitry Vyukov, Konstantin Khlebnikov,
	Andrey Ryabinin, Viacheslav Garbuzov

On 10/17/2014 04:12 PM, Jakub Jelinek wrote:
> I had a brief look at what ended up on the branch in the end, and
> from what I understand, the 4.9 libasan.so has
> __asan_report_store_n and __asan_report_load_n entry points, but does
> not have any __asan_loadN/__asan_reportN entrypoints (neither 1/2/4/8/16,
> nor variable).
> So, what the branch does seems to not match what the library provides.

I agree, __asan_report_loadN is indeed there and misalign tests seem to 
pass fine. Probably I should have examined 4.9 libasan closer.

> With -fsanitize=address -O2 --param asan-instrumentation-with-call-threshold=0
> foo is again unexpectedly not instrumented, and bar is instrumented
> with __asan_load8, which looks wrong to me, because the library does not
> provide any such entry point.

By default asan-instrumentation-with-call-threshold is INT_MAX which 
means that compiler will never generate __asan_load*/__asan_store* calls 
unless forced by the user (e.g. for Kasan).

> But, in execute_sanopt force !use_calls
> for (flag_sanitize & SANITIZE_USER_ADDRESS).

Do you think above limitation is not enough?

> Thus, IMHO the:
>    if ((flag_sanitize & SANITIZE_USER_ADDRESS) != 0
>        && ((size_in_bytes & (size_in_bytes - 1)) != 0
> 	  || (unsigned HOST_WIDE_INT) size_in_bytes - 1 >= 16))
>      return;
> should be nuked from 4.9, we can do unaligned/non-{1,2,4,8,16}
> accesses fine.

Right. I'd also import misalign tests.

> Or were there any bugfixes needed for __asan_report_{store,load}_n
> on the library side?

I don't think so.

-Y

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 0/17] KASan 4.9 backport
  2014-10-17 13:49   ` Yury Gribov
@ 2014-10-17 14:02     ` Jakub Jelinek
  2014-10-17 14:15       ` Yury Gribov
  0 siblings, 1 reply; 49+ messages in thread
From: Jakub Jelinek @ 2014-10-17 14:02 UTC (permalink / raw)
  To: Yury Gribov
  Cc: GCC Patches, Dmitry Vyukov, Konstantin Khlebnikov,
	Andrey Ryabinin, Viacheslav Garbuzov

On Fri, Oct 17, 2014 at 05:45:17PM +0400, Yury Gribov wrote:
> On 10/17/2014 04:12 PM, Jakub Jelinek wrote:
> >I had a brief look at what ended up on the branch in the end, and
> >from what I understand, the 4.9 libasan.so has
> >__asan_report_store_n and __asan_report_load_n entry points, but does
> >not have any __asan_loadN/__asan_reportN entrypoints (neither 1/2/4/8/16,
> >nor variable).
> >So, what the branch does seems to not match what the library provides.
> 
> I agree, __asan_report_loadN is indeed there and misalign tests seem to pass
> fine. Probably I should have examined 4.9 libasan closer.
> 
> >With -fsanitize=address -O2 --param asan-instrumentation-with-call-threshold=0
> >foo is again unexpectedly not instrumented, and bar is instrumented
> >with __asan_load8, which looks wrong to me, because the library does not
> >provide any such entry point.
> 
> By default asan-instrumentation-with-call-threshold is INT_MAX which means
> that compiler will never generate __asan_load*/__asan_store* calls unless
> forced by the user (e.g. for Kasan).
> 
> >But, in execute_sanopt force !use_calls
> >for (flag_sanitize & SANITIZE_USER_ADDRESS).
> 
> Do you think above limitation is not enough?

Yeah, even if the default is that it doesn't make the non-existing calls,
anyone who uses the parameter will get code that doesn't link.

> 
> >Thus, IMHO the:
> >   if ((flag_sanitize & SANITIZE_USER_ADDRESS) != 0
> >       && ((size_in_bytes & (size_in_bytes - 1)) != 0
> >	  || (unsigned HOST_WIDE_INT) size_in_bytes - 1 >= 16))
> >     return;
> >should be nuked from 4.9, we can do unaligned/non-{1,2,4,8,16}
> >accesses fine.
> 
> Right. I'd also import misalign tests.
> 
> >Or were there any bugfixes needed for __asan_report_{store,load}_n
> >on the library side?
> 
> I don't think so.

So, what about this?  Just checked that with
make -k check-g{cc,++} RUNTESTFLAGS='--target_board=unix\{-m32,-m64\} asan.exp tsan.exp ubsan.exp'
so far.  Plus if you add misalign tests...

2014-10-17  Jakub Jelinek  <jakub@redhat.com>

	* asan.c (instrument_derefs): Allow instrumentation of odd-sized
	accesses even for -fsanitize=address.
	(execute_sanopt): Only allow use_calls for -fsanitize=kernel-address.

	* c-c++-common/asan/instrument-with-calls-1.c: Add
	-fno-sanitize=address -fsanitize=kernel-address to dg-options.
	* c-c++-common/asan/instrument-with-calls-2.c: Likewise.

--- gcc/asan.c.jj	2014-10-17 12:51:27.000000000 +0200
+++ gcc/asan.c	2014-10-17 15:21:29.921495259 +0200
@@ -1707,10 +1707,6 @@ instrument_derefs (gimple_stmt_iterator
   size_in_bytes = int_size_in_bytes (type);
   if (size_in_bytes <= 0)
     return;
-  if ((flag_sanitize & SANITIZE_USER_ADDRESS) != 0
-      && ((size_in_bytes & (size_in_bytes - 1)) != 0
-	  || (unsigned HOST_WIDE_INT) size_in_bytes - 1 >= 16))
-    return;
 
   HOST_WIDE_INT bitsize, bitpos;
   tree offset;
@@ -2780,8 +2776,10 @@ execute_sanopt (void)
 	  }
     }
 
-  bool use_calls = ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD < INT_MAX
-    && asan_num_accesses >= ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD;
+  bool use_calls
+    = ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD < INT_MAX
+      && (flag_sanitize & SANITIZE_KERNEL_ADDRESS)
+      && asan_num_accesses >= ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD;
 
   FOR_EACH_BB_FN (bb, cfun)
     {
--- gcc/testsuite/c-c++-common/asan/instrument-with-calls-1.c.jj	2014-10-17 12:51:27.000000000 +0200
+++ gcc/testsuite/c-c++-common/asan/instrument-with-calls-1.c	2014-10-17 15:34:06.679627168 +0200
@@ -1,5 +1,5 @@
 /* { dg-do assemble } */
-/* { dg-options "--param asan-instrumentation-with-call-threshold=0 -save-temps" } */
+/* { dg-options "-fno-sanitize=address -fsanitize=kernel-address --param asan-instrumentation-with-call-threshold=0 -save-temps" } */
 
 void f(char *a, int *b) {
   *b = *a;
--- gcc/testsuite/c-c++-common/asan/instrument-with-calls-2.c.jj	2014-10-17 12:51:27.000000000 +0200
+++ gcc/testsuite/c-c++-common/asan/instrument-with-calls-2.c	2014-10-17 15:34:15.569472032 +0200
@@ -1,5 +1,5 @@
 /* { dg-do assemble } */
-/* { dg-options "--param asan-instrumentation-with-call-threshold=1 -save-temps" } */
+/* { dg-options "-fno-sanitize=address -fsanitize=kernel-address --param asan-instrumentation-with-call-threshold=1 -save-temps" } */
 
 int x;
 


	Jakub

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 0/17] KASan 4.9 backport
  2014-10-17 14:02     ` Jakub Jelinek
@ 2014-10-17 14:15       ` Yury Gribov
  2014-10-17 14:21         ` Jakub Jelinek
  0 siblings, 1 reply; 49+ messages in thread
From: Yury Gribov @ 2014-10-17 14:15 UTC (permalink / raw)
  To: Jakub Jelinek
  Cc: GCC Patches, Dmitry Vyukov, Konstantin Khlebnikov,
	Andrey Ryabinin, Viacheslav Garbuzov

On 10/17/2014 05:49 PM, Jakub Jelinek wrote:
 > Plus if you add misalign tests...

Sure, can do this on Monday.

 > -  bool use_calls = ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD < INT_MAX
> -    && asan_num_accesses >= ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD;
> +  bool use_calls
> +    = ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD < INT_MAX
> +      && (flag_sanitize & SANITIZE_KERNEL_ADDRESS)
> +      && asan_num_accesses >= ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD;

I agree that original code didn't quite match GNU conventions but can we 
avoid reformatting it to make future backports easier? So e.g.

  bool use_calls = ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD < INT_MAX
+    && (flag_sanitize & SANITIZE_KERNEL_ADDRESS)
    && asan_num_accesses >= ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD;

-Y

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 0/17] KASan 4.9 backport
  2014-10-17 14:15       ` Yury Gribov
@ 2014-10-17 14:21         ` Jakub Jelinek
  2014-10-17 14:38           ` Yury Gribov
  0 siblings, 1 reply; 49+ messages in thread
From: Jakub Jelinek @ 2014-10-17 14:21 UTC (permalink / raw)
  To: Yury Gribov
  Cc: GCC Patches, Dmitry Vyukov, Konstantin Khlebnikov,
	Andrey Ryabinin, Viacheslav Garbuzov

On Fri, Oct 17, 2014 at 06:15:11PM +0400, Yury Gribov wrote:
> On 10/17/2014 05:49 PM, Jakub Jelinek wrote:
> > Plus if you add misalign tests...
> 
> Sure, can do this on Monday.

Ok, thanks.

> > -  bool use_calls = ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD < INT_MAX
> >-    && asan_num_accesses >= ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD;
> >+  bool use_calls
> >+    = ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD < INT_MAX
> >+      && (flag_sanitize & SANITIZE_KERNEL_ADDRESS)
> >+      && asan_num_accesses >= ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD;
> 
> I agree that original code didn't quite match GNU conventions but can we
> avoid reformatting it to make future backports easier? So e.g.
> 
>  bool use_calls = ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD < INT_MAX
> +    && (flag_sanitize & SANITIZE_KERNEL_ADDRESS)
>    && asan_num_accesses >= ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD;

I can live with that.  So here is updated patch:

2014-10-17  Jakub Jelinek  <jakub@redhat.com>

	* asan.c (instrument_derefs): Allow instrumentation of odd-sized
	accesses even for -fsanitize=address.
	(execute_sanopt): Only allow use_calls for -fsanitize=kernel-address.

	* c-c++-common/asan/instrument-with-calls-1.c: Add
	-fno-sanitize=address -fsanitize=kernel-address to dg-options.
	* c-c++-common/asan/instrument-with-calls-2.c: Likewise.

--- gcc/asan.c.jj	2014-10-17 12:51:27.000000000 +0200
+++ gcc/asan.c	2014-10-17 15:21:29.921495259 +0200
@@ -1707,10 +1707,6 @@ instrument_derefs (gimple_stmt_iterator
   size_in_bytes = int_size_in_bytes (type);
   if (size_in_bytes <= 0)
     return;
-  if ((flag_sanitize & SANITIZE_USER_ADDRESS) != 0
-      && ((size_in_bytes & (size_in_bytes - 1)) != 0
-	  || (unsigned HOST_WIDE_INT) size_in_bytes - 1 >= 16))
-    return;
 
   HOST_WIDE_INT bitsize, bitpos;
   tree offset;
@@ -2781,6 +2777,7 @@ execute_sanopt (void)
     }
 
   bool use_calls = ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD < INT_MAX
+    && (flag_sanitize & SANITIZE_KERNEL_ADDRESS)
     && asan_num_accesses >= ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD;
 
   FOR_EACH_BB_FN (bb, cfun)
--- gcc/testsuite/c-c++-common/asan/instrument-with-calls-1.c.jj	2014-10-17 12:51:27.000000000 +0200
+++ gcc/testsuite/c-c++-common/asan/instrument-with-calls-1.c	2014-10-17 15:34:06.679627168 +0200
@@ -1,5 +1,5 @@
 /* { dg-do assemble } */
-/* { dg-options "--param asan-instrumentation-with-call-threshold=0 -save-temps" } */
+/* { dg-options "-fno-sanitize=address -fsanitize=kernel-address --param asan-instrumentation-with-call-threshold=0 -save-temps" } */
 
 void f(char *a, int *b) {
   *b = *a;
--- gcc/testsuite/c-c++-common/asan/instrument-with-calls-2.c.jj	2014-10-17 12:51:27.000000000 +0200
+++ gcc/testsuite/c-c++-common/asan/instrument-with-calls-2.c	2014-10-17 15:34:15.569472032 +0200
@@ -1,5 +1,5 @@
 /* { dg-do assemble } */
-/* { dg-options "--param asan-instrumentation-with-call-threshold=1 -save-temps" } */
+/* { dg-options "-fno-sanitize=address -fsanitize=kernel-address --param asan-instrumentation-with-call-threshold=1 -save-temps" } */
 
 int x;
 


	Jakub

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH 0/17] KASan 4.9 backport
  2014-10-17 14:21         ` Jakub Jelinek
@ 2014-10-17 14:38           ` Yury Gribov
  2014-10-20 10:40             ` [PATCH] Backport misalign tests to 4.9 Yury Gribov
  0 siblings, 1 reply; 49+ messages in thread
From: Yury Gribov @ 2014-10-17 14:38 UTC (permalink / raw)
  To: Jakub Jelinek
  Cc: GCC Patches, Dmitry Vyukov, Konstantin Khlebnikov,
	Andrey Ryabinin, Viacheslav Garbuzov

On 10/17/2014 06:18 PM, Jakub Jelinek wrote:
> On Fri, Oct 17, 2014 at 06:15:11PM +0400, Yury Gribov wrote:
>> On 10/17/2014 05:49 PM, Jakub Jelinek wrote:
>>> Plus if you add misalign tests...
>>
>> Sure, can do this on Monday.
>
> Ok, thanks.
>
>>> -  bool use_calls = ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD < INT_MAX
>>> -    && asan_num_accesses >= ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD;
>>> +  bool use_calls
>>> +    = ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD < INT_MAX
>>> +      && (flag_sanitize & SANITIZE_KERNEL_ADDRESS)
>>> +      && asan_num_accesses >= ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD;
>>
>> I agree that original code didn't quite match GNU conventions but can we
>> avoid reformatting it to make future backports easier? So e.g.
>>
>>   bool use_calls = ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD < INT_MAX
>> +    && (flag_sanitize & SANITIZE_KERNEL_ADDRESS)
>>     && asan_num_accesses >= ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD;
>
> I can live with that.  So here is updated patch:

Thanks, LGTM.

-Y



^ permalink raw reply	[flat|nested] 49+ messages in thread

* [PATCH] Backport misalign tests to 4.9
  2014-10-17 14:38           ` Yury Gribov
@ 2014-10-20 10:40             ` Yury Gribov
  2014-10-20 10:47               ` Jakub Jelinek
  0 siblings, 1 reply; 49+ messages in thread
From: Yury Gribov @ 2014-10-20 10:40 UTC (permalink / raw)
  To: Jakub Jelinek
  Cc: GCC Patches, Dmitry Vyukov, Konstantin Khlebnikov,
	Andrey Ryabinin, Viacheslav Garbuzov

[-- Attachment #1: Type: text/plain, Size: 414 bytes --]

On Fri, Oct 17, 2014 at 06:15:11PM +0400, Yury Gribov wrote:
> On 10/17/2014 05:49 PM, Jakub Jelinek wrote:
 >> So, what about this?  Just checked that with
 >> make -k check-g{cc,++} 
RUNTESTFLAGS='--target_board=unix\{-m32,-m64\} asan.exp tsan.exp ubsan.exp'
 >> so far.  Plus if you add misalign tests...
>
> Sure, can do this on Monday.

Here are the said tests, passed (on x64) as expected. Ok to commit?

-Y

[-- Attachment #2: misalign-backport-1.diff --]
[-- Type: text/x-patch, Size: 3184 bytes --]

commit f4007db6a5f90f71fe977c8232ea7fe2de1c6c28
Author: jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Date:   Fri May 30 18:37:59 2014 +0000

    2014-10-20  Yury Gribov  <y.gribov@samsung.com>
    
    	Backported from mainline
    	2014-05-30  Jakub Jelinek  <jakub@redhat.com>
    
    	* c-c++-common/asan/misalign-1.c: New test.
    	* c-c++-common/asan/misalign-2.c: New test.

diff --git a/gcc/testsuite/c-c++-common/asan/misalign-1.c b/gcc/testsuite/c-c++-common/asan/misalign-1.c
new file mode 100644
index 0000000..0c5b6e0
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/asan/misalign-1.c
@@ -0,0 +1,42 @@
+/* { dg-do run { target { ilp32 || lp64 } } } */
+/* { dg-options "-O2" } */
+/* { dg-shouldfail "asan" } */
+
+struct S { int i; } __attribute__ ((packed));
+
+__attribute__((noinline, noclone)) int
+foo (struct S *s)
+{
+  return s->i;
+}
+
+__attribute__((noinline, noclone)) int
+bar (int *s)
+{
+  return *s;
+}
+
+__attribute__((noinline, noclone)) struct S
+baz (struct S *s)
+{
+  return *s;
+}
+
+int
+main ()
+{
+  struct T { char a[3]; struct S b[3]; char c; } t;
+  int v = 5;
+  struct S *p = t.b;
+  asm volatile ("" : "+rm" (p));
+  p += 3;
+  if (bar (&v) != 5) __builtin_abort ();
+  volatile int w = foo (p);
+  return 0;
+}
+
+/* { dg-output "ERROR: AddressSanitizer:\[^\n\r]*on address\[^\n\r]*" } */
+/* { dg-output "0x\[0-9a-f\]+ at pc 0x\[0-9a-f\]+ bp 0x\[0-9a-f\]+ sp 0x\[0-9a-f\]+\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*READ of size 4 at 0x\[0-9a-f\]+ thread T0\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "    #0 0x\[0-9a-f\]+ (in _*foo(\[^\n\r]*misalign-1.c:10|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "    #1 0x\[0-9a-f\]+ (in _*main (\[^\n\r]*misalign-1.c:34|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } */
diff --git a/gcc/testsuite/c-c++-common/asan/misalign-2.c b/gcc/testsuite/c-c++-common/asan/misalign-2.c
new file mode 100644
index 0000000..7fbe299
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/asan/misalign-2.c
@@ -0,0 +1,42 @@
+/* { dg-do run { target { ilp32 || lp64 } } } */
+/* { dg-options "-O2" } */
+/* { dg-shouldfail "asan" } */
+
+struct S { int i; } __attribute__ ((packed));
+
+__attribute__((noinline, noclone)) int
+foo (struct S *s)
+{
+  return s->i;
+}
+
+__attribute__((noinline, noclone)) int
+bar (int *s)
+{
+  return *s;
+}
+
+__attribute__((noinline, noclone)) struct S
+baz (struct S *s)
+{
+  return *s;
+}
+
+int
+main ()
+{
+  struct T { char a[3]; struct S b[3]; char c; } t;
+  int v = 5;
+  struct S *p = t.b;
+  asm volatile ("" : "+rm" (p));
+  p += 3;
+  if (bar (&v) != 5) __builtin_abort ();
+  volatile struct S w = baz (p);
+  return 0;
+}
+
+/* { dg-output "ERROR: AddressSanitizer:\[^\n\r]*on address\[^\n\r]*" } */
+/* { dg-output "0x\[0-9a-f\]+ at pc 0x\[0-9a-f\]+ bp 0x\[0-9a-f\]+ sp 0x\[0-9a-f\]+\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*READ of size 4 at 0x\[0-9a-f\]+ thread T0\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "    #0 0x\[0-9a-f\]+ (in _*baz(\[^\n\r]*misalign-2.c:22|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "    #1 0x\[0-9a-f\]+ (in _*main (\[^\n\r]*misalign-2.c:34|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } */

^ permalink raw reply	[flat|nested] 49+ messages in thread

* Re: [PATCH] Backport misalign tests to 4.9
  2014-10-20 10:40             ` [PATCH] Backport misalign tests to 4.9 Yury Gribov
@ 2014-10-20 10:47               ` Jakub Jelinek
  0 siblings, 0 replies; 49+ messages in thread
From: Jakub Jelinek @ 2014-10-20 10:47 UTC (permalink / raw)
  To: Yury Gribov
  Cc: GCC Patches, Dmitry Vyukov, Konstantin Khlebnikov,
	Andrey Ryabinin, Viacheslav Garbuzov

On Mon, Oct 20, 2014 at 02:37:21PM +0400, Yury Gribov wrote:
> On Fri, Oct 17, 2014 at 06:15:11PM +0400, Yury Gribov wrote:
> >On 10/17/2014 05:49 PM, Jakub Jelinek wrote:
> >> So, what about this?  Just checked that with
> >> make -k check-g{cc,++} RUNTESTFLAGS='--target_board=unix\{-m32,-m64\}
> asan.exp tsan.exp ubsan.exp'
> >> so far.  Plus if you add misalign tests...
> >
> >Sure, can do this on Monday.
> 
> Here are the said tests, passed (on x64) as expected. Ok to commit?
> 
> -Y

> commit f4007db6a5f90f71fe977c8232ea7fe2de1c6c28
> Author: jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
> Date:   Fri May 30 18:37:59 2014 +0000
> 
>     2014-10-20  Yury Gribov  <y.gribov@samsung.com>
>     
>     	Backported from mainline
>     	2014-05-30  Jakub Jelinek  <jakub@redhat.com>
>     
>     	* c-c++-common/asan/misalign-1.c: New test.
>     	* c-c++-common/asan/misalign-2.c: New test.

Ok, thanks.

	Jakub

^ permalink raw reply	[flat|nested] 49+ messages in thread

end of thread, other threads:[~2014-10-20 10:44 UTC | newest]

Thread overview: 49+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-10-16  8:35 [PATCH 0/17] KASan 4.9 backport Yury Gribov
2014-10-16  8:36 ` [PATCH 1/17] Install asan_interface.h Yury Gribov
2014-10-16  8:41   ` Jakub Jelinek
2014-10-16  8:36 ` [PATCH 3/17] Instrumentation of unaligned types Yury Gribov
2014-10-16  8:45   ` Jakub Jelinek
2014-10-16  8:37 ` [PATCH 4/17] Outline instrumentation Yury Gribov
2014-10-16  8:46   ` Jakub Jelinek
2014-10-16  8:37 ` [PATCH 2/17] Introduction of __asan_loadN/__asan_storeN Yury Gribov
2014-10-16  8:44   ` Jakub Jelinek
2014-10-16  8:38 ` [PATCH 6/17] Fix for PR 61530 Yury Gribov
2014-10-16  8:47   ` Jakub Jelinek
2014-10-16  8:38 ` [PATCH 5/17] Fix bootstrap error Yury Gribov
2014-10-16  8:47   ` Jakub Jelinek
2014-10-16  8:39 ` [PATCH 7/17] Fix for PR 61547 Yury Gribov
2014-10-16  8:49   ` Jakub Jelinek
2014-10-16  8:39 ` [PATCH 8/17] Optimization of strlen instrumentation Yury Gribov
2014-10-16  8:50   ` Jakub Jelinek
2014-10-16  9:06     ` Yury Gribov
2014-10-16  8:40 ` [PATCH 9/17] Initial KAsan support Yury Gribov
2014-10-16  8:51   ` Jakub Jelinek
2014-10-17  7:29   ` Eric Botcazou
2014-10-17  7:44     ` Yury Gribov
2014-10-17  7:49       ` Eric Botcazou
2014-10-17  8:45         ` Yury Gribov
2014-10-17 12:04           ` Jakub Jelinek
2014-10-16  8:40 ` [PATCH 10/17] Support fnspec for internal fns Yury Gribov
2014-10-16  8:52   ` Jakub Jelinek
2014-10-16  8:41 ` [PATCH 13/17] Fix for PR 62089 Yury Gribov
2014-10-16  8:53   ` Jakub Jelinek
2014-10-16  8:41 ` [PATCH 11/17] Move Asan instrumentation to sanopt pass Yury Gribov
2014-10-16  8:52   ` Jakub Jelinek
2014-10-16  8:41 ` [PATCH 12/17] Fix off-by-one Yury Gribov
2014-10-16  8:53   ` Jakub Jelinek
2014-10-16  8:42 ` [PATCH 14/17] Fix test on 32-bit platforms Yury Gribov
2014-10-16  8:54   ` Jakub Jelinek
2014-10-16  8:42 ` [PATCH 15/17] Fix for PR 61897 and PR 62140 Yury Gribov
2014-10-16  8:54   ` Jakub Jelinek
2014-10-16  8:43 ` [PATCH 16/17] Disable __asan_init calls for KASan Yury Gribov
2014-10-16  8:55   ` Jakub Jelinek
2014-10-16  8:44 ` [PATCH 17/17] Enable __asan_loadN/__asan_storeN " Yury Gribov
2014-10-16  9:03   ` Jakub Jelinek
2014-10-17 12:21 ` [PATCH 0/17] KASan 4.9 backport Jakub Jelinek
2014-10-17 13:49   ` Yury Gribov
2014-10-17 14:02     ` Jakub Jelinek
2014-10-17 14:15       ` Yury Gribov
2014-10-17 14:21         ` Jakub Jelinek
2014-10-17 14:38           ` Yury Gribov
2014-10-20 10:40             ` [PATCH] Backport misalign tests to 4.9 Yury Gribov
2014-10-20 10:47               ` Jakub Jelinek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).