On April 5, 2017 12:01:37 PM GMT+02:00, Jakub Jelinek <ja...@redhat.com> wrote: >Hi! > >When asan unpoisons variables that don't have byte sizes that are >multiples >of 8, it on big endian stores the last chunk size value into the first >byte >rather than last byte, so e.g. for the variable of size 12 bytes in the >testcase it stores half-word 0x0400 into the shadow memory, which is >fine >on little-endian (we want bytes 0x00 0x04), but wrong on big-endian. >We don't support asan on pdp-endian targets. > >Bootstrapped/regtested on powerpc64-linux, ok for trunk?
OK. Richard. >2017-04-05 Jakub Jelinek <ja...@redhat.com> > Bernd Edlinger <bernd.edlin...@hotmail.de> > > PR sanitizer/80308 > * asan.c (asan_store_shadow_bytes): Fix location of last_chunk_value > for big endian. > > * c-c++-common/asan/pr80308.c: New test. > >--- gcc/asan.c.jj 2017-03-27 10:24:33.000000000 +0200 >+++ gcc/asan.c 2017-04-05 08:19:00.512439980 +0200 >@@ -2757,10 +2757,13 @@ asan_store_shadow_bytes (gimple_stmt_ite > >unsigned char c = (char) is_clobber ? ASAN_STACK_MAGIC_USE_AFTER_SCOPE >: 0; > unsigned HOST_WIDE_INT val = 0; >+ unsigned last_pos = size; >+ if (last_chunk_size && !is_clobber) >+ last_pos = BYTES_BIG_ENDIAN ? 0 : size - 1; > for (unsigned i = 0; i < size; ++i) > { > unsigned char shadow_c = c; >- if (i == size - 1 && last_chunk_size && !is_clobber) >+ if (i == last_pos) > shadow_c = last_chunk_size; > val |= (unsigned HOST_WIDE_INT) shadow_c << (BITS_PER_UNIT * i); > } >--- gcc/testsuite/c-c++-common/asan/pr80308.c.jj 2017-04-05 >08:14:10.373364559 +0200 >+++ gcc/testsuite/c-c++-common/asan/pr80308.c 2017-04-05 >08:13:40.000000000 +0200 >@@ -0,0 +1,25 @@ >+/* PR sanitizer/80308 */ >+/* { dg-do run } */ >+ >+__attribute__((noinline, noclone)) int >+foo (char *a) >+{ >+ int i, j = 0; >+ asm volatile ("" : "+r" (a) : : "memory"); >+ for (i = 0; i < 12; i++) >+ j += a[i]; >+ return j; >+} >+ >+int >+main () >+{ >+ int i, j = 0; >+ for (i = 0; i < 4; i++) >+ { >+ char a[12]; >+ __builtin_memset (a, 0, sizeof (a)); >+ j += foo (a); >+ } >+ return j; >+} > > Jakub