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
5 changed files with 134 additions and 10 deletions
|
@ -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
|
||||
|
|
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). */
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
42
gcc/testsuite/c-c++-common/asan/misalign-1.c
Normal file
42
gcc/testsuite/c-c++-common/asan/misalign-1.c
Normal file
|
@ -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)" } */
|
42
gcc/testsuite/c-c++-common/asan/misalign-2.c
Normal file
42
gcc/testsuite/c-c++-common/asan/misalign-2.c
Normal file
|
@ -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…
Add table
Reference in a new issue