diff options
author | Jakub Jelinek <jakub@redhat.com> | 2013-02-16 10:32:56 +0100 |
---|---|---|
committer | Dodji Seketeli <dodji@gcc.gnu.org> | 2013-02-16 10:32:56 +0100 |
commit | b41288b3a57a382c7e06ef0f847584f06583ceb4 (patch) | |
tree | 8d20d0d3ec1ed8a33b52873e900b4acbeff14e5c | |
parent | 4d0648ac8ff3df5e4525fe8da00906493742c72c (diff) | |
download | gcc-b41288b3a57a382c7e06ef0f847584f06583ceb4.zip gcc-b41288b3a57a382c7e06ef0f847584f06583ceb4.tar.gz gcc-b41288b3a57a382c7e06ef0f847584f06583ceb4.tar.bz2 |
[asan] Fix for PR asan/56330
gcc/
* asan.c (get_mem_refs_of_builtin_call): White space and style
cleanup.
(instrument_mem_region_access): Do not forget to always put
instrumentation of the of 'base' and 'base + len' in a "if (len !=
0) statement, even for cases where either 'base' or 'base + len'
are not instrumented -- because they have been previously
instrumented. Simplify the logic by putting all the statements
instrument 'base + len' inside a sequence, and then insert that
sequence right before the current insertion point. Then, to
instrument 'base + len', just get an iterator on that statement.
And do not forget to update the pointer to iterator the function
received as argument.
gcc/testsuite/
* c-c++-common/asan/no-redundant-instrumentation-4.c: New test file.
* 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/pr56330.c: Likewise.
* c-c++-common/asan/no-redundant-instrumentation-1.c (test1):
Ensure the size argument of __builtin_memcpy is a constant.
Co-Authored-By: Dodji Seketeli <dodji@redhat.com>
From-SVN: r196102
-rw-r--r-- | gcc/ChangeLog | 17 | ||||
-rw-r--r-- | gcc/asan.c | 97 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 13 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-1.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-4.c | 13 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-5.c | 13 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-6.c | 14 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-7.c | 23 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-8.c | 14 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/asan/pr56330.c | 24 |
10 files changed, 185 insertions, 45 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 928eef4..07d5b8a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,20 @@ +2013-02-16 Jakub Jelinek <jakub@redhat.com> + Dodji Seketeli <dodji@redhat.com> + + PR asan/56330 + * asan.c (get_mem_refs_of_builtin_call): White space and style + cleanup. + (instrument_mem_region_access): Do not forget to always put + instrumentation of the of 'base' and 'base + len' in a "if (len != + 0) statement, even for cases where either 'base' or 'base + len' + are not instrumented -- because they have been previously + instrumented. Simplify the logic by putting all the statements + instrument 'base + len' inside a sequence, and then insert that + sequence right before the current insertion point. Then, to + instrument 'base + len', just get an iterator on that statement. + And do not forget to update the pointer to iterator the function + received as argument. + 2013-02-15 Vladimir Makarov <vmakarov@redhat.com> PR rtl-optimization/56348 @@ -747,20 +747,17 @@ get_mem_refs_of_builtin_call (const gimple call, got_reference_p = true; } - else - { - if (dest) - { - dst->start = dest; - dst->access_size = access_size; - *dst_len = NULL_TREE; - *dst_is_store = is_store; - *dest_is_deref = true; - got_reference_p = true; - } - } + else if (dest) + { + dst->start = dest; + dst->access_size = access_size; + *dst_len = NULL_TREE; + *dst_is_store = is_store; + *dest_is_deref = true; + got_reference_p = true; + } - return got_reference_p; + return got_reference_p; } /* Return true iff a given gimple statement has been instrumented. @@ -1535,8 +1532,15 @@ instrument_mem_region_access (tree base, tree len, /* If the beginning of the memory region has already been instrumented, do not instrument it. */ - if (has_mem_ref_been_instrumented (base, 1)) - goto after_first_instrumentation; + 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. */ + 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; if (!is_gimple_constant (len)) { @@ -1562,37 +1566,39 @@ instrument_mem_region_access (tree base, tree len, /* The 'then block' of the 'if (len != 0) condition is where we'll generate the asan instrumentation code now. */ - gsi = gsi_start_bb (then_bb); + gsi = gsi_last_bb (then_bb); } - /* 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; - - update_mem_ref_hash_table (base, 1); + 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); + } + } - after_first_instrumentation: + if (end_instrumented) + return; /* We want to instrument the access at the end of the memory region, which is at (base + len - 1). */ - /* If the end of the memory region has already been instrumented, do - not instrument it. */ - tree end = asan_mem_ref_get_end (base, len); - if (has_mem_ref_been_instrumented (end, 1)) - return; - /* offset = len - 1; */ len = unshare_expr (len); tree offset; @@ -1639,8 +1645,6 @@ instrument_mem_region_access (tree base, tree len, base, NULL); gimple_set_location (region_end, location); gimple_seq_add_stmt_without_update (&seq, region_end); - gsi_insert_seq_before (&gsi, seq, GSI_SAME_STMT); - gsi_prev (&gsi); /* _2 = _1 + offset; */ region_end = @@ -1649,13 +1653,18 @@ instrument_mem_region_access (tree base, tree len, gimple_assign_lhs (region_end), offset); gimple_set_location (region_end, location); - gsi_insert_after (&gsi, region_end, GSI_NEW_STMT); + 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); - update_mem_ref_hash_table (end, 1); + if (then_bb == NULL) + update_mem_ref_hash_table (end, 1); + + *iter = gsi_for_stmt (gsi_stmt (*iter)); } /* Instrument the call (to the builtin strlen function) pointed to by @@ -1783,7 +1792,7 @@ instrument_builtin_call (gimple_stmt_iterator *iter) } else if (src0_len || src1_len || dest_len) { - if (src0.start) + if (src0.start != NULL_TREE) instrument_mem_region_access (src0.start, src0_len, iter, loc, /*is_store=*/false); if (src1.start != NULL_TREE) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d2e1e57..1508a65 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,16 @@ +2013-02-16 Jakub Jelinek <jakub@redhat.com> + Dodji Seketeli <dodji@redhat.com> + + PR asan/56330 + * c-c++-common/asan/no-redundant-instrumentation-4.c: New test file. + * 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/pr56330.c: Likewise. + * c-c++-common/asan/no-redundant-instrumentation-1.c (test1): + Ensure the size argument of __builtin_memcpy is a constant. + 2013-02-15 Jonathan Wakely <jwakely.gcc@gmail.com> Paolo Carlini <paolo.carlini@oracle.com> 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 cc98fdb..6cf6441 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 @@ -45,7 +45,7 @@ test1 () /* There are 2 calls to __builtin___asan_report_store1 and 2 calls to __builtin___asan_report_load1 to instrument the store to (subset of) the memory region of tab. */ - __builtin_memcpy (&tab[1], foo, sizeof (tab) - 1); + __builtin_memcpy (&tab[1], foo, 3); /* This should not generate a __builtin___asan_report_load1 because the reference to tab[1] has been already instrumented above. */ 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 new file mode 100644 index 0000000..b2e7284 --- /dev/null +++ b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-4.c @@ -0,0 +1,13 @@ +/* { dg-options "-fdump-tree-asan0" } */ +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "*" } { "-O0" } } */ + +void +foo (int *a, char *b, char *c) +{ + __builtin_memmove (c, b, a[c[0]]); +} + +/* { 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 { 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 new file mode 100644 index 0000000..ead3f58 --- /dev/null +++ b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-5.c @@ -0,0 +1,13 @@ +/* { dg-options "-fdump-tree-asan0" } */ +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "*" } { "-O0" } } */ + +void +foo (int *a, char *b, char *c) +{ + __builtin_memmove (c, b, a[b[0]]); +} + +/* { 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 { 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 new file mode 100644 index 0000000..e4691bc --- /dev/null +++ b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-6.c @@ -0,0 +1,14 @@ +/* { dg-options "-fdump-tree-asan0" } */ +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "*" } { "-O0" } } */ + +void +foo (int *a, char *b, char *c) +{ + __builtin_memmove (c, b, a[c[0]]); + __builtin_memmove (c, b, a[b[0]]); +} + +/* { 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 { 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 new file mode 100644 index 0000000..075e9cf --- /dev/null +++ b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-7.c @@ -0,0 +1,23 @@ +/* { dg-options "-fdump-tree-asan0" } */ +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "*" } { "-O0" } } */ + +char e[200]; + +struct S +{ + char a[100]; + char b[100]; +} s; + +int +foo (int *a, char *b, char *c) +{ + int d = __builtin_memcmp (s.a, e, 100); + d += __builtin_memcmp (s.a, e, 200); + return d; +} + +/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load" 6 "asan0" } } */ +/* { dg-final { scan-tree-dump-not "__builtin___asan_report_store" "asan0" } } */ +/* { dg-final { cleanup-tree-dump "asan" } } */ 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 new file mode 100644 index 0000000..38ea7a2 --- /dev/null +++ b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-8.c @@ -0,0 +1,14 @@ +/* { dg-options "-fdump-tree-asan0" } */ +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "*" } { "-O0" } } */ + +char +foo (int *a, char *b, char *c) +{ + __builtin_memmove (c, b, a[b[0]]); + return c[0] + b[0]; +} + +/* { 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 { cleanup-tree-dump "asan0" } } */ diff --git a/gcc/testsuite/c-c++-common/asan/pr56330.c b/gcc/testsuite/c-c++-common/asan/pr56330.c new file mode 100644 index 0000000..25759f4 --- /dev/null +++ b/gcc/testsuite/c-c++-common/asan/pr56330.c @@ -0,0 +1,24 @@ +/* PR sanitizer/56330 */ +/* { dg-do compile } */ + +char e[200]; + +struct S +{ + char a[100]; + char b[100]; +} s; + +int +foo (void) +{ + int i = __builtin_memcmp (s.a, e, 100); + i += __builtin_memcmp (s.a, e, 200); + return i; +} + +void +bar (int *a, char *b, char *c) +{ + __builtin_memmove (c, b, a[b[0]]); +} |