aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2014-05-30 20:37:59 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2014-05-30 20:37:59 +0200
commitb3f1051b11374792241ae7f72f015ce2325bb492 (patch)
treec81e52a0dcb4b5084747f6e4eaaa18d3cfa498cd
parent40f9f6bb0ead69f2e09b62341e91a0f9643afe3f (diff)
downloadgcc-b3f1051b11374792241ae7f72f015ce2325bb492.zip
gcc-b3f1051b11374792241ae7f72f015ce2325bb492.tar.gz
gcc-b3f1051b11374792241ae7f72f015ce2325bb492.tar.bz2
asan.c (report_error_func): Add SLOW_P argument, use BUILT_IN_ASAN_*_N if set.
* 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. * c-c++-common/asan/misalign-1.c: New test. * c-c++-common/asan/misalign-2.c: New test. From-SVN: r211092
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/asan.c51
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/c-c++-common/asan/misalign-1.c42
-rw-r--r--gcc/testsuite/c-c++-common/asan/misalign-2.c42
5 files changed, 134 insertions, 10 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3d20e13..233f05f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,11 @@
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.
+
* 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
diff --git a/gcc/asan.c b/gcc/asan.c
index beb0023..3397655 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);
@@ -1722,8 +1730,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);
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 8beaf53..89cb55c 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,8 @@
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.
+
* g++.dg/asan/asan_test.C: Add -std=c++11 and
-DSANITIZER_USE_DEJAGNU_GTEST=1 to dg-options, remove
-DASAN_USE_DEJAGNU_GTEST=1.
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)" } */