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
This commit is contained in:
parent
40f9f6bb0e
commit
b3f1051b11
|
@ -1,5 +1,11 @@
|
||||||
2014-05-30 Jakub Jelinek <jakub@redhat.com>
|
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,
|
* sanitizer.def (BUILT_IN_ASAN_REPORT_LOAD_N,
|
||||||
BUILT_IN_ASAN_REPORT_STORE_N): New.
|
BUILT_IN_ASAN_REPORT_STORE_N): New.
|
||||||
* asan.c (struct asan_mem_ref): Change access_size type to
|
* asan.c (struct asan_mem_ref): Change access_size type to
|
||||||
|
|
51
gcc/asan.c
51
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). */
|
IS_STORE is either 1 (for a store) or 0 (for a load). */
|
||||||
|
|
||||||
static tree
|
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]
|
static enum built_in_function report[2][6]
|
||||||
= { { BUILT_IN_ASAN_REPORT_LOAD1, BUILT_IN_ASAN_REPORT_LOAD2,
|
= { { 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_STORE4, BUILT_IN_ASAN_REPORT_STORE8,
|
||||||
BUILT_IN_ASAN_REPORT_STORE16, BUILT_IN_ASAN_REPORT_STORE_N } };
|
BUILT_IN_ASAN_REPORT_STORE16, BUILT_IN_ASAN_REPORT_STORE_N } };
|
||||||
if ((size_in_bytes & (size_in_bytes - 1)) != 0
|
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][5]);
|
||||||
return builtin_decl_implicit (report[is_store][exact_log2 (size_in_bytes)]);
|
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
|
static void
|
||||||
build_check_stmt (location_t location, tree base, gimple_stmt_iterator *iter,
|
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;
|
gimple_stmt_iterator gsi;
|
||||||
basic_block then_bb, else_bb;
|
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;
|
HOST_WIDE_INT real_size_in_bytes = size_in_bytes;
|
||||||
tree sz_arg = NULL_TREE;
|
tree sz_arg = NULL_TREE;
|
||||||
|
|
||||||
if ((size_in_bytes & (size_in_bytes - 1)) != 0
|
if (size_in_bytes == 1)
|
||||||
|| size_in_bytes > 16)
|
slow_p = false;
|
||||||
real_size_in_bytes = 1;
|
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
|
/* Get an iterator on the point where we can add the condition
|
||||||
statement for the instrumentation. */
|
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));
|
t = gimple_assign_lhs (gimple_seq_last (seq));
|
||||||
gimple_seq_set_location (seq, location);
|
gimple_seq_set_location (seq, location);
|
||||||
gsi_insert_seq_after (&gsi, seq, GSI_CONTINUE_LINKING);
|
gsi_insert_seq_after (&gsi, seq, GSI_CONTINUE_LINKING);
|
||||||
/* For weird access sizes, check first and last byte. */
|
/* For weird access sizes or misaligned, check first and last byte. */
|
||||||
if (real_size_in_bytes != size_in_bytes)
|
if (slow_p)
|
||||||
{
|
{
|
||||||
g = gimple_build_assign_with_ops (PLUS_EXPR,
|
g = gimple_build_assign_with_ops (PLUS_EXPR,
|
||||||
make_ssa_name (uintptr_type, NULL),
|
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). */
|
/* Generate call to the run-time library (e.g. __asan_report_load8). */
|
||||||
gsi = gsi_start_bb (then_bb);
|
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);
|
sz_arg ? 2 : 1, base_addr, sz_arg);
|
||||||
gimple_set_location (g, location);
|
gimple_set_location (g, location);
|
||||||
gsi_insert_after (&gsi, g, GSI_NEW_STMT);
|
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);
|
base = build_fold_addr_expr (t);
|
||||||
if (!has_mem_ref_been_instrumented (base, size_in_bytes))
|
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,
|
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 (base, size_in_bytes);
|
||||||
update_mem_ref_hash_table (t, size_in_bytes);
|
update_mem_ref_hash_table (t, size_in_bytes);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
2014-05-30 Jakub Jelinek <jakub@redhat.com>
|
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
|
* g++.dg/asan/asan_test.C: Add -std=c++11 and
|
||||||
-DSANITIZER_USE_DEJAGNU_GTEST=1 to dg-options, remove
|
-DSANITIZER_USE_DEJAGNU_GTEST=1 to dg-options, remove
|
||||||
-DASAN_USE_DEJAGNU_GTEST=1.
|
-DASAN_USE_DEJAGNU_GTEST=1.
|
||||||
|
|
|
@ -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)" } */
|
|
@ -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)" } */
|
Loading…
Reference in New Issue