Message ID | CAKdteOY1Qoe1dXTSGSgABp3RPi+4+ge-XreNr9URK4kLjbfRQQ@mail.gmail.com |
---|---|
State | New |
Headers | show |
+eugenis@google.com (our ARM expert) Christophe, The change in sanitizer_common/sanitizer_stacktrace.cc changes the logic which is known to work well for us on Android/ARM. I'd like Evgeniy to comment on it. --kcc On Mon, May 6, 2013 at 10:52 PM, Christophe Lyon <christophe.lyon@linaro.org> wrote: > Hi, > > Here is a 2nd attempt at enabling libsanitizer on ARM. > Compared with the previous version, this patch is more intrusive to > workaround some limitations with qemu: > > * qemu does not work well with threads, so I chose to disable > clone-test-1.c and rlimit-mmap-test-1.c when running on a simulator. > This is a bit overkill since the limitation is caused by qemu, not by > the fact of running on a simulator. Would it cause problems on other > targets? > > * due to different connexion mathod between runtest and the target > program in native mode and in simulated mode, causing isatty(2) to > give a different answer, I modified a few regexps to accept possible > decorations. This can be removed once ASAN_OPTIONS=color=0 is > implemented. > > Tested on x86 with no regression, on ARM cortex-a9 hardware and > a15-qemu with the expected new tests. > > OK? > > Christophe. > > 2013-05-06 Christophe Lyon <christophe.lyon@linaro.org> > > gcc/ > * config/arm/arm.c (arm_asan_shadow_offset): New function. > (TARGET_ASAN_SHADOW_OFFSET): Define. > * config/arm/linux-eabi.h (ASAN_CC1_SPEC): Define. > (LINUX_OR_ANDROID_CC): Add ASAN_CC1_SPEC. > > libsanitizer/ > * configure.tgt: Add ARM pattern. > * sanitizer_common/sanitizer_stacktrace.cc: Return the computed > value. > > testsuite/ > * lib/target-supports.exp (check_effective_target_hw): New > function. > * c-c++-common/asan/clone-test-1.c: Call > check_effective_target_hw. > * c-c++-common/asan/rlimit-mmap-test-1.c: Likewise. > * c-c++-common/asan/heap-overflow-1.c: Update regexps to accept > possible decorations. > * c-c++-common/asan/null-deref-1.c: Likewise. > * c-c++-common/asan/stack-overflow-1.c: Likewise. > * c-c++-common/asan/strncpy-overflow-1.c: Likewise. > * c-c++-common/asan/use-after-free-1.c: Likewise. > * g++.dg/asan/deep-thread-stack-1.C: Likewise. > * g++.dg/asan/large-func-test-1.C: Likewise. > > diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c > index 0b97cf8..c036a21 100644 > --- a/gcc/config/arm/arm.c > +++ b/gcc/config/arm/arm.c > @@ -281,6 +281,8 @@ static unsigned arm_add_stmt_cost (void *data, int count, > > static void arm_canonicalize_comparison (int *code, rtx *op0, rtx *op1, > bool op0_preserve_value); > +static unsigned HOST_WIDE_INT arm_asan_shadow_offset (void); > + > > /* Table of machine attributes. */ > static const struct attribute_spec arm_attribute_table[] = > @@ -657,6 +659,9 @@ static const struct attribute_spec arm_attribute_table[] = > #define TARGET_CANONICALIZE_COMPARISON \ > arm_canonicalize_comparison > > +#undef TARGET_ASAN_SHADOW_OFFSET > +#define TARGET_ASAN_SHADOW_OFFSET arm_asan_shadow_offset > + > struct gcc_target targetm = TARGET_INITIALIZER; > > /* Obstack for minipool constant handling. */ > @@ -28062,4 +28067,12 @@ arm_validize_comparison (rtx *comparison, rtx > * op1, rtx * op2) > > } > > +/* Implement the TARGET_ASAN_SHADOW_OFFSET hook. */ > + > +static unsigned HOST_WIDE_INT > +arm_asan_shadow_offset (void) > +{ > + return (unsigned HOST_WIDE_INT) 1 << 29; > +} > + > #include "gt-arm.h" > diff --git a/gcc/config/arm/linux-eabi.h b/gcc/config/arm/linux-eabi.h > index 23671a7..cb0aad1 100644 > --- a/gcc/config/arm/linux-eabi.h > +++ b/gcc/config/arm/linux-eabi.h > @@ -84,10 +84,14 @@ > LINUX_OR_ANDROID_LD (LINUX_TARGET_LINK_SPEC, \ > LINUX_TARGET_LINK_SPEC " " ANDROID_LINK_SPEC) > > +#undef ASAN_CC1_SPEC > +#define ASAN_CC1_SPEC "%{fsanitize=*:-funwind-tables}" > + > #undef CC1_SPEC > #define CC1_SPEC \ > - LINUX_OR_ANDROID_CC (GNU_USER_TARGET_CC1_SPEC, \ > - GNU_USER_TARGET_CC1_SPEC " " ANDROID_CC1_SPEC) > + LINUX_OR_ANDROID_CC (GNU_USER_TARGET_CC1_SPEC " " ASAN_CC1_SPEC, \ > + GNU_USER_TARGET_CC1_SPEC " " ASAN_CC1_SPEC " " \ > + ANDROID_CC1_SPEC) > > #define CC1PLUS_SPEC \ > LINUX_OR_ANDROID_CC ("", ANDROID_CC1PLUS_SPEC) > diff --git a/gcc/testsuite/c-c++-common/asan/clone-test-1.c > b/gcc/testsuite/c-c++-common/asan/clone-test-1.c > index d9acc0d..fd187aa 100644 > --- a/gcc/testsuite/c-c++-common/asan/clone-test-1.c > +++ b/gcc/testsuite/c-c++-common/asan/clone-test-1.c > @@ -3,6 +3,7 @@ > > /* { dg-do run { target { *-*-linux* } } } */ > /* { dg-require-effective-target clone } */ > +/* { dg-require-effective-target hw } */ > /* { dg-options "-D_GNU_SOURCE" } */ > > #include <stdio.h> > diff --git a/gcc/testsuite/c-c++-common/asan/heap-overflow-1.c > b/gcc/testsuite/c-c++-common/asan/heap-overflow-1.c > index 43d47a3..e0b9038 100644 > --- a/gcc/testsuite/c-c++-common/asan/heap-overflow-1.c > +++ b/gcc/testsuite/c-c++-common/asan/heap-overflow-1.c > @@ -25,7 +25,7 @@ int main(int argc, char **argv) { > > /* { dg-output "READ of size 1 at 0x\[0-9a-f\]+ thread T0.*(\n|\r\n|\r)" } */ > /* { dg-output " #0 0x\[0-9a-f\]+ (in _*main > (\[^\n\r]*heap-overflow-1.c:21|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } */ > -/* { dg-output "0x\[0-9a-f\]+ is located 0 bytes to the right of > 10-byte region\[^\n\r]*(\n|\r\n|\r)" } */ > -/* { dg-output "allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */ > +/* { dg-output ".*0x\[0-9a-f\]+ is located 0 bytes to the right of > 10-byte region\[^\n\r]*(\n|\r\n|\r)" } */ > +/* { dg-output ".*allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */ > /* { dg-output " #0 0x\[0-9a-f\]+ (in > _*(interceptor_|)malloc|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ > /* { dg-output " #1 0x\[0-9a-f\]+ (in _*main > (\[^\n\r]*heap-overflow-1.c:19|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" > } */ > diff --git a/gcc/testsuite/c-c++-common/asan/null-deref-1.c > b/gcc/testsuite/c-c++-common/asan/null-deref-1.c > index 2eee986..95e5036 100644 > --- a/gcc/testsuite/c-c++-common/asan/null-deref-1.c > +++ b/gcc/testsuite/c-c++-common/asan/null-deref-1.c > @@ -18,6 +18,6 @@ int main() > > /* { dg-output "ERROR: AddressSanitizer:? SEGV on unknown > address\[^\n\r]*" } */ > /* { dg-output "0x\[0-9a-f\]+ \[^\n\r]*pc > 0x\[0-9a-f\]+\[^\n\r]*(\n|\r\n|\r)" } */ > -/* { dg-output "AddressSanitizer can not provide additional > info.*(\n|\r\n|\r)" } */ > +/* { dg-output ".*AddressSanitizer can not provide additional > info.*(\n|\r\n|\r)" } */ > /* { dg-output " #0 0x\[0-9a-f\]+ (in \[^\n\r]*NullDeref\[^\n\r]* > (\[^\n\r]*null-deref-1.c:10|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" > } */ > /* { dg-output " #1 0x\[0-9a-f\]+ (in _*main > (\[^\n\r]*null-deref-1.c:15|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" > } */ > diff --git a/gcc/testsuite/c-c++-common/asan/rlimit-mmap-test-1.c > b/gcc/testsuite/c-c++-common/asan/rlimit-mmap-test-1.c > index 0b3d2ae..9dbbc85 100644 > --- a/gcc/testsuite/c-c++-common/asan/rlimit-mmap-test-1.c > +++ b/gcc/testsuite/c-c++-common/asan/rlimit-mmap-test-1.c > @@ -2,6 +2,7 @@ > > /* { dg-do run { target setrlimit } } */ > /* { dg-skip-if "" { *-*-* } { "*" } { "-O0" } } */ > +/* { dg-require-effective-target hw } */ > /* { dg-shouldfail "asan" } */ > > #include <stdlib.h> > diff --git a/gcc/testsuite/c-c++-common/asan/stack-overflow-1.c > b/gcc/testsuite/c-c++-common/asan/stack-overflow-1.c > index 790aa5e..5788b10 100644 > --- a/gcc/testsuite/c-c++-common/asan/stack-overflow-1.c > +++ b/gcc/testsuite/c-c++-common/asan/stack-overflow-1.c > @@ -19,4 +19,4 @@ int main() { > > /* { dg-output "READ of size 1 at 0x\[0-9a-f\]+ thread > T0\[^\n\r]*(\n|\r\n|\r)" } */ > /* { dg-output " #0 0x\[0-9a-f\]+ (in _*main > (\[^\n\r]*stack-overflow-1.c:16|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } > */ > -/* { dg-output "Address 0x\[0-9a-f\]+ is\[^\n\r]*frame <main>" } */ > +/* { dg-output ".*Address 0x\[0-9a-f\]+ is\[^\n\r]*frame <main>" } */ > diff --git a/gcc/testsuite/c-c++-common/asan/strncpy-overflow-1.c > b/gcc/testsuite/c-c++-common/asan/strncpy-overflow-1.c > index 10b3ad7..5e8ce40 100644 > --- a/gcc/testsuite/c-c++-common/asan/strncpy-overflow-1.c > +++ b/gcc/testsuite/c-c++-common/asan/strncpy-overflow-1.c > @@ -15,7 +15,7 @@ int main(int argc, char **argv) { > /* { dg-output "WRITE of size \[0-9\]* at 0x\[0-9a-f\]+ thread > T0\[^\n\r]*(\n|\r\n|\r)" } */ > /* { dg-output " #0 0x\[0-9a-f\]+ (in > _*(interceptor_|)strncpy|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ > /* { dg-output " #1 0x\[0-9a-f\]+ (in _*main > (\[^\n\r]*strncpy-overflow-1.c:11|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } > */ > -/* { dg-output "0x\[0-9a-f\]+ is located 0 bytes to the right of > 9-byte region\[^\n\r]*(\n|\r\n|\r)" } */ > -/* { dg-output "allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */ > +/* { dg-output ".*0x\[0-9a-f\]+ is located 0 bytes to the right of > 9-byte region\[^\n\r]*(\n|\r\n|\r)" } */ > +/* { dg-output ".*allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */ > /* { dg-output " #0 0x\[0-9a-f\]+ (in > _*(interceptor_|)malloc|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ > /* { dg-output " #1 0x\[0-9a-f\]+ (in _*main > (\[^\n\r]*strncpy-overflow-1.c:10|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" > } */ > diff --git a/gcc/testsuite/c-c++-common/asan/use-after-free-1.c > b/gcc/testsuite/c-c++-common/asan/use-after-free-1.c > index 939feeb..65318c8 100644 > --- a/gcc/testsuite/c-c++-common/asan/use-after-free-1.c > +++ b/gcc/testsuite/c-c++-common/asan/use-after-free-1.c > @@ -11,12 +11,12 @@ int main() { > > /* { dg-output "ERROR: AddressSanitizer:? heap-use-after-free 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 "READ of size 1 at 0x\[0-9a-f\]+ thread > T0\[^\n\r]*(\n|\r\n|\r)" } */ > +/* { dg-output ".*READ of size 1 at 0x\[0-9a-f\]+ thread > T0\[^\n\r]*(\n|\r\n|\r)" } */ > /* { dg-output " #0 0x\[0-9a-f\]+ (in _*main > (\[^\n\r]*use-after-free-1.c:9|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } */ > -/* { dg-output "0x\[0-9a-f\]+ is located 5 bytes inside of 10-byte > region .0x\[0-9a-f\]+,0x\[0-9a-f\]+\[^\n\r]*(\n|\r\n|\r)" } */ > -/* { dg-output "freed by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */ > +/* { dg-output ".*0x\[0-9a-f\]+ is located 5 bytes inside of 10-byte > region .0x\[0-9a-f\]+,0x\[0-9a-f\]+\[^\n\r]*(\n|\r\n|\r)" } */ > +/* { dg-output ".*freed by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */ > /* { dg-output " #0 0x\[0-9a-f\]+ (in > _*(interceptor_|)free|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ > /* { dg-output " #1 0x\[0-9a-f\]+ (in _*main > (\[^\n\r]*use-after-free-1.c:8|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } */ > -/* { dg-output "previously allocated by thread T0 > here:\[^\n\r]*(\n|\r\n|\r)" } */ > +/* { dg-output ".*previously allocated by thread T0 > here:\[^\n\r]*(\n|\r\n|\r)" } */ > /* { dg-output " #0 0x\[0-9a-f\]+ (in > _*(interceptor_|)malloc|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ > /* { dg-output " #1 0x\[0-9a-f\]+ (in _*main > (\[^\n\r]*use-after-free-1.c:7|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" > } */ > diff --git a/gcc/testsuite/g++.dg/asan/deep-thread-stack-1.C > b/gcc/testsuite/g++.dg/asan/deep-thread-stack-1.C > index 12d8a7a..d29fe31 100644 > --- a/gcc/testsuite/g++.dg/asan/deep-thread-stack-1.C > +++ b/gcc/testsuite/g++.dg/asan/deep-thread-stack-1.C > @@ -45,9 +45,9 @@ int main(int argc, char *argv[]) { > } > > // { dg-output "ERROR: AddressSanitizer: heap-use-after-free.*(\n|\r\n|\r)" } > -// { dg-output "WRITE of size 4 at 0x\[0-9a-f\]+ thread > T(\[0-9\]+).*(\n|\r\n|\r)" } > -// { dg-output "freed by thread T(\[0-9\]+) here:.*(\n|\r\n|\r)" } > -// { dg-output "previously allocated by thread T(\[0-9\]+) > here:.*(\n|\r\n|\r)" } > +// { dg-output ".*WRITE of size 4 at 0x\[0-9a-f\]+ thread > T(\[0-9\]+).*(\n|\r\n|\r)" } > +// { dg-output ".*freed by thread T(\[0-9\]+) here:.*(\n|\r\n|\r)" } > +// { dg-output ".*previously allocated by thread T(\[0-9\]+) > here:.*(\n|\r\n|\r)" } > // { dg-output "Thread T\\2 created by T(\[0-9\]+) here:.*(\n|\r\n|\r)" } > // { dg-output "Thread T\\8 created by T0 here:.*(\n|\r\n|\r)" } > // { dg-output "Thread T\\4 created by T(\[0-9\]+) here:.*(\n|\r\n|\r)" } > diff --git a/gcc/testsuite/g++.dg/asan/large-func-test-1.C > b/gcc/testsuite/g++.dg/asan/large-func-test-1.C > index 32808e7..0d5c383 100644 > --- a/gcc/testsuite/g++.dg/asan/large-func-test-1.C > +++ b/gcc/testsuite/g++.dg/asan/large-func-test-1.C > @@ -37,9 +37,9 @@ int main() { > > // { dg-output "ERROR: AddressSanitizer:? heap-buffer-overflow 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 "READ of size 4 at 0x\[0-9a-f\]+ thread > T0\[^\n\r]*(\n|\r\n|\r)" } > +// { dg-output ".*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 > \[^\n\r]*LargeFunction\[^\n\r]*(large-func-test-1.C:18|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" > } > -// { dg-output "0x\[0-9a-f\]+ is located 44 bytes to the right of > 400-byte region.*(\n|\r\n|\r)" } > -// { dg-output "allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } > +// { dg-output ".*0x\[0-9a-f\]+ is located 44 bytes to the right of > 400-byte region.*(\n|\r\n|\r)" } > +// { dg-output ".*allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } > // { dg-output " #0( 0x\[0-9a-f\]+ (in > _*(interceptor_|)malloc|\[(\])\[^\n\r]*(\n|\r\n|\r)" } > // { dg-output " #1|) 0x\[0-9a-f\]+ (in (operator > new|_*_Zn\[aw\]\[mj\])|\[(\])\[^\n\r]*(\n|\r\n|\r)" } > diff --git a/gcc/testsuite/lib/target-supports.exp > b/gcc/testsuite/lib/target-supports.exp > index 45c8b84..28b6b6d 100644 > --- a/gcc/testsuite/lib/target-supports.exp > +++ b/gcc/testsuite/lib/target-supports.exp > @@ -4668,6 +4668,33 @@ proc check_effective_target_simulator { } { > return 0 > } > > +# Return 1 if programs are intended to be run on hardware rather than > +# on a simulator > + > +proc check_effective_target_hw { } { > + > + # All "src/sim" simulators set this one. > + if [board_info target exists is_simulator] { > + if [board_info target is_simulator] { > + return 0 > + } else { > + return 1 > + } > + } > + > + # The "sid" simulators don't set that one, but at least they set > + # this one. > + if [board_info target exists slow_simulator] { > + if [board_info target slow_simulator] { > + return 0 > + } else { > + return 1 > + } > + } > + > + return 1 > +} > + > # Return 1 if the target is a VxWorks kernel. > > proc check_effective_target_vxworks_kernel { } { > diff --git a/libsanitizer/configure.tgt b/libsanitizer/configure.tgt > index 265da01..bdfc22e 100644 > --- a/libsanitizer/configure.tgt > +++ b/libsanitizer/configure.tgt > @@ -29,6 +29,8 @@ case "${target}" in > ;; > sparc*-*-linux*) > ;; > + arm*-*-linux*) > + ;; > x86_64-*-darwin[1]* | i?86-*-darwin[1]*) > TSAN_SUPPORTED=no > ;; > diff --git a/libsanitizer/sanitizer_common/sanitizer_stacktrace.cc > b/libsanitizer/sanitizer_common/sanitizer_stacktrace.cc > index e14ea44..7b3e4ca 100644 > --- a/libsanitizer/sanitizer_common/sanitizer_stacktrace.cc > +++ b/libsanitizer/sanitizer_common/sanitizer_stacktrace.cc > @@ -27,7 +27,7 @@ const char *StripPathPrefix(const char *filepath, > uptr StackTrace::GetPreviousInstructionPc(uptr pc) { > #ifdef __arm__ > // Cancel Thumb bit. > - pc = pc & (~1); > + return pc & (~1); > #endif > #if defined(__powerpc__) || defined(__powerpc64__) > // PCs are always 4 byte aligned.
On Tue, May 7, 2013 at 9:33 AM, Konstantin Serebryany <konstantin.s.serebryany@gmail.com> wrote: > +eugenis@google.com (our ARM expert) > > Christophe, > > The change in sanitizer_common/sanitizer_stacktrace.cc changes the > logic which is known to work well for us on Android/ARM. > I'd like Evgeniy to comment on it. > > --kcc > > On Mon, May 6, 2013 at 10:52 PM, Christophe Lyon > <christophe.lyon@linaro.org> wrote: >> Hi, >> >> Here is a 2nd attempt at enabling libsanitizer on ARM. >> Compared with the previous version, this patch is more intrusive to >> workaround some limitations with qemu: >> >> * qemu does not work well with threads, so I chose to disable >> clone-test-1.c and rlimit-mmap-test-1.c when running on a simulator. >> This is a bit overkill since the limitation is caused by qemu, not by >> the fact of running on a simulator. Would it cause problems on other >> targets? >> >> * due to different connexion mathod between runtest and the target >> program in native mode and in simulated mode, causing isatty(2) to >> give a different answer, I modified a few regexps to accept possible >> decorations. This can be removed once ASAN_OPTIONS=color=0 is >> implemented. >> >> Tested on x86 with no regression, on ARM cortex-a9 hardware and >> a15-qemu with the expected new tests. >> >> OK? >> >> Christophe. >> >> 2013-05-06 Christophe Lyon <christophe.lyon@linaro.org> >> >> gcc/ >> * config/arm/arm.c (arm_asan_shadow_offset): New function. >> (TARGET_ASAN_SHADOW_OFFSET): Define. >> * config/arm/linux-eabi.h (ASAN_CC1_SPEC): Define. >> (LINUX_OR_ANDROID_CC): Add ASAN_CC1_SPEC. >> >> libsanitizer/ >> * configure.tgt: Add ARM pattern. >> * sanitizer_common/sanitizer_stacktrace.cc: Return the computed >> value. >> >> testsuite/ >> * lib/target-supports.exp (check_effective_target_hw): New >> function. >> * c-c++-common/asan/clone-test-1.c: Call >> check_effective_target_hw. >> * c-c++-common/asan/rlimit-mmap-test-1.c: Likewise. >> * c-c++-common/asan/heap-overflow-1.c: Update regexps to accept >> possible decorations. >> * c-c++-common/asan/null-deref-1.c: Likewise. >> * c-c++-common/asan/stack-overflow-1.c: Likewise. >> * c-c++-common/asan/strncpy-overflow-1.c: Likewise. >> * c-c++-common/asan/use-after-free-1.c: Likewise. >> * g++.dg/asan/deep-thread-stack-1.C: Likewise. >> * g++.dg/asan/large-func-test-1.C: Likewise. >> >> diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c >> index 0b97cf8..c036a21 100644 >> --- a/gcc/config/arm/arm.c >> +++ b/gcc/config/arm/arm.c >> @@ -281,6 +281,8 @@ static unsigned arm_add_stmt_cost (void *data, int count, >> >> static void arm_canonicalize_comparison (int *code, rtx *op0, rtx *op1, >> bool op0_preserve_value); >> +static unsigned HOST_WIDE_INT arm_asan_shadow_offset (void); >> + >> >> /* Table of machine attributes. */ >> static const struct attribute_spec arm_attribute_table[] = >> @@ -657,6 +659,9 @@ static const struct attribute_spec arm_attribute_table[] = >> #define TARGET_CANONICALIZE_COMPARISON \ >> arm_canonicalize_comparison >> >> +#undef TARGET_ASAN_SHADOW_OFFSET >> +#define TARGET_ASAN_SHADOW_OFFSET arm_asan_shadow_offset >> + >> struct gcc_target targetm = TARGET_INITIALIZER; >> >> /* Obstack for minipool constant handling. */ >> @@ -28062,4 +28067,12 @@ arm_validize_comparison (rtx *comparison, rtx >> * op1, rtx * op2) >> >> } >> >> +/* Implement the TARGET_ASAN_SHADOW_OFFSET hook. */ >> + >> +static unsigned HOST_WIDE_INT >> +arm_asan_shadow_offset (void) >> +{ >> + return (unsigned HOST_WIDE_INT) 1 << 29; >> +} >> + >> #include "gt-arm.h" >> diff --git a/gcc/config/arm/linux-eabi.h b/gcc/config/arm/linux-eabi.h >> index 23671a7..cb0aad1 100644 >> --- a/gcc/config/arm/linux-eabi.h >> +++ b/gcc/config/arm/linux-eabi.h >> @@ -84,10 +84,14 @@ >> LINUX_OR_ANDROID_LD (LINUX_TARGET_LINK_SPEC, \ >> LINUX_TARGET_LINK_SPEC " " ANDROID_LINK_SPEC) >> >> +#undef ASAN_CC1_SPEC >> +#define ASAN_CC1_SPEC "%{fsanitize=*:-funwind-tables}" >> + >> #undef CC1_SPEC >> #define CC1_SPEC \ >> - LINUX_OR_ANDROID_CC (GNU_USER_TARGET_CC1_SPEC, \ >> - GNU_USER_TARGET_CC1_SPEC " " ANDROID_CC1_SPEC) >> + LINUX_OR_ANDROID_CC (GNU_USER_TARGET_CC1_SPEC " " ASAN_CC1_SPEC, \ >> + GNU_USER_TARGET_CC1_SPEC " " ASAN_CC1_SPEC " " \ >> + ANDROID_CC1_SPEC) >> >> #define CC1PLUS_SPEC \ >> LINUX_OR_ANDROID_CC ("", ANDROID_CC1PLUS_SPEC) >> diff --git a/gcc/testsuite/c-c++-common/asan/clone-test-1.c >> b/gcc/testsuite/c-c++-common/asan/clone-test-1.c >> index d9acc0d..fd187aa 100644 >> --- a/gcc/testsuite/c-c++-common/asan/clone-test-1.c >> +++ b/gcc/testsuite/c-c++-common/asan/clone-test-1.c >> @@ -3,6 +3,7 @@ >> >> /* { dg-do run { target { *-*-linux* } } } */ >> /* { dg-require-effective-target clone } */ >> +/* { dg-require-effective-target hw } */ >> /* { dg-options "-D_GNU_SOURCE" } */ >> >> #include <stdio.h> >> diff --git a/gcc/testsuite/c-c++-common/asan/heap-overflow-1.c >> b/gcc/testsuite/c-c++-common/asan/heap-overflow-1.c >> index 43d47a3..e0b9038 100644 >> --- a/gcc/testsuite/c-c++-common/asan/heap-overflow-1.c >> +++ b/gcc/testsuite/c-c++-common/asan/heap-overflow-1.c >> @@ -25,7 +25,7 @@ int main(int argc, char **argv) { >> >> /* { dg-output "READ of size 1 at 0x\[0-9a-f\]+ thread T0.*(\n|\r\n|\r)" } */ >> /* { dg-output " #0 0x\[0-9a-f\]+ (in _*main >> (\[^\n\r]*heap-overflow-1.c:21|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } */ >> -/* { dg-output "0x\[0-9a-f\]+ is located 0 bytes to the right of >> 10-byte region\[^\n\r]*(\n|\r\n|\r)" } */ >> -/* { dg-output "allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */ >> +/* { dg-output ".*0x\[0-9a-f\]+ is located 0 bytes to the right of >> 10-byte region\[^\n\r]*(\n|\r\n|\r)" } */ >> +/* { dg-output ".*allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */ >> /* { dg-output " #0 0x\[0-9a-f\]+ (in >> _*(interceptor_|)malloc|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ >> /* { dg-output " #1 0x\[0-9a-f\]+ (in _*main >> (\[^\n\r]*heap-overflow-1.c:19|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" >> } */ >> diff --git a/gcc/testsuite/c-c++-common/asan/null-deref-1.c >> b/gcc/testsuite/c-c++-common/asan/null-deref-1.c >> index 2eee986..95e5036 100644 >> --- a/gcc/testsuite/c-c++-common/asan/null-deref-1.c >> +++ b/gcc/testsuite/c-c++-common/asan/null-deref-1.c >> @@ -18,6 +18,6 @@ int main() >> >> /* { dg-output "ERROR: AddressSanitizer:? SEGV on unknown >> address\[^\n\r]*" } */ >> /* { dg-output "0x\[0-9a-f\]+ \[^\n\r]*pc >> 0x\[0-9a-f\]+\[^\n\r]*(\n|\r\n|\r)" } */ >> -/* { dg-output "AddressSanitizer can not provide additional >> info.*(\n|\r\n|\r)" } */ >> +/* { dg-output ".*AddressSanitizer can not provide additional >> info.*(\n|\r\n|\r)" } */ >> /* { dg-output " #0 0x\[0-9a-f\]+ (in \[^\n\r]*NullDeref\[^\n\r]* >> (\[^\n\r]*null-deref-1.c:10|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" >> } */ >> /* { dg-output " #1 0x\[0-9a-f\]+ (in _*main >> (\[^\n\r]*null-deref-1.c:15|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" >> } */ >> diff --git a/gcc/testsuite/c-c++-common/asan/rlimit-mmap-test-1.c >> b/gcc/testsuite/c-c++-common/asan/rlimit-mmap-test-1.c >> index 0b3d2ae..9dbbc85 100644 >> --- a/gcc/testsuite/c-c++-common/asan/rlimit-mmap-test-1.c >> +++ b/gcc/testsuite/c-c++-common/asan/rlimit-mmap-test-1.c >> @@ -2,6 +2,7 @@ >> >> /* { dg-do run { target setrlimit } } */ >> /* { dg-skip-if "" { *-*-* } { "*" } { "-O0" } } */ >> +/* { dg-require-effective-target hw } */ >> /* { dg-shouldfail "asan" } */ >> >> #include <stdlib.h> >> diff --git a/gcc/testsuite/c-c++-common/asan/stack-overflow-1.c >> b/gcc/testsuite/c-c++-common/asan/stack-overflow-1.c >> index 790aa5e..5788b10 100644 >> --- a/gcc/testsuite/c-c++-common/asan/stack-overflow-1.c >> +++ b/gcc/testsuite/c-c++-common/asan/stack-overflow-1.c >> @@ -19,4 +19,4 @@ int main() { >> >> /* { dg-output "READ of size 1 at 0x\[0-9a-f\]+ thread >> T0\[^\n\r]*(\n|\r\n|\r)" } */ >> /* { dg-output " #0 0x\[0-9a-f\]+ (in _*main >> (\[^\n\r]*stack-overflow-1.c:16|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } >> */ >> -/* { dg-output "Address 0x\[0-9a-f\]+ is\[^\n\r]*frame <main>" } */ >> +/* { dg-output ".*Address 0x\[0-9a-f\]+ is\[^\n\r]*frame <main>" } */ >> diff --git a/gcc/testsuite/c-c++-common/asan/strncpy-overflow-1.c >> b/gcc/testsuite/c-c++-common/asan/strncpy-overflow-1.c >> index 10b3ad7..5e8ce40 100644 >> --- a/gcc/testsuite/c-c++-common/asan/strncpy-overflow-1.c >> +++ b/gcc/testsuite/c-c++-common/asan/strncpy-overflow-1.c >> @@ -15,7 +15,7 @@ int main(int argc, char **argv) { >> /* { dg-output "WRITE of size \[0-9\]* at 0x\[0-9a-f\]+ thread >> T0\[^\n\r]*(\n|\r\n|\r)" } */ >> /* { dg-output " #0 0x\[0-9a-f\]+ (in >> _*(interceptor_|)strncpy|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ >> /* { dg-output " #1 0x\[0-9a-f\]+ (in _*main >> (\[^\n\r]*strncpy-overflow-1.c:11|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } >> */ >> -/* { dg-output "0x\[0-9a-f\]+ is located 0 bytes to the right of >> 9-byte region\[^\n\r]*(\n|\r\n|\r)" } */ >> -/* { dg-output "allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */ >> +/* { dg-output ".*0x\[0-9a-f\]+ is located 0 bytes to the right of >> 9-byte region\[^\n\r]*(\n|\r\n|\r)" } */ >> +/* { dg-output ".*allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */ >> /* { dg-output " #0 0x\[0-9a-f\]+ (in >> _*(interceptor_|)malloc|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ >> /* { dg-output " #1 0x\[0-9a-f\]+ (in _*main >> (\[^\n\r]*strncpy-overflow-1.c:10|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" >> } */ >> diff --git a/gcc/testsuite/c-c++-common/asan/use-after-free-1.c >> b/gcc/testsuite/c-c++-common/asan/use-after-free-1.c >> index 939feeb..65318c8 100644 >> --- a/gcc/testsuite/c-c++-common/asan/use-after-free-1.c >> +++ b/gcc/testsuite/c-c++-common/asan/use-after-free-1.c >> @@ -11,12 +11,12 @@ int main() { >> >> /* { dg-output "ERROR: AddressSanitizer:? heap-use-after-free 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 "READ of size 1 at 0x\[0-9a-f\]+ thread >> T0\[^\n\r]*(\n|\r\n|\r)" } */ >> +/* { dg-output ".*READ of size 1 at 0x\[0-9a-f\]+ thread >> T0\[^\n\r]*(\n|\r\n|\r)" } */ >> /* { dg-output " #0 0x\[0-9a-f\]+ (in _*main >> (\[^\n\r]*use-after-free-1.c:9|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } */ >> -/* { dg-output "0x\[0-9a-f\]+ is located 5 bytes inside of 10-byte >> region .0x\[0-9a-f\]+,0x\[0-9a-f\]+\[^\n\r]*(\n|\r\n|\r)" } */ >> -/* { dg-output "freed by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */ >> +/* { dg-output ".*0x\[0-9a-f\]+ is located 5 bytes inside of 10-byte >> region .0x\[0-9a-f\]+,0x\[0-9a-f\]+\[^\n\r]*(\n|\r\n|\r)" } */ >> +/* { dg-output ".*freed by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */ >> /* { dg-output " #0 0x\[0-9a-f\]+ (in >> _*(interceptor_|)free|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ >> /* { dg-output " #1 0x\[0-9a-f\]+ (in _*main >> (\[^\n\r]*use-after-free-1.c:8|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } */ >> -/* { dg-output "previously allocated by thread T0 >> here:\[^\n\r]*(\n|\r\n|\r)" } */ >> +/* { dg-output ".*previously allocated by thread T0 >> here:\[^\n\r]*(\n|\r\n|\r)" } */ >> /* { dg-output " #0 0x\[0-9a-f\]+ (in >> _*(interceptor_|)malloc|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ >> /* { dg-output " #1 0x\[0-9a-f\]+ (in _*main >> (\[^\n\r]*use-after-free-1.c:7|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" >> } */ >> diff --git a/gcc/testsuite/g++.dg/asan/deep-thread-stack-1.C >> b/gcc/testsuite/g++.dg/asan/deep-thread-stack-1.C >> index 12d8a7a..d29fe31 100644 >> --- a/gcc/testsuite/g++.dg/asan/deep-thread-stack-1.C >> +++ b/gcc/testsuite/g++.dg/asan/deep-thread-stack-1.C >> @@ -45,9 +45,9 @@ int main(int argc, char *argv[]) { >> } >> >> // { dg-output "ERROR: AddressSanitizer: heap-use-after-free.*(\n|\r\n|\r)" } >> -// { dg-output "WRITE of size 4 at 0x\[0-9a-f\]+ thread >> T(\[0-9\]+).*(\n|\r\n|\r)" } >> -// { dg-output "freed by thread T(\[0-9\]+) here:.*(\n|\r\n|\r)" } >> -// { dg-output "previously allocated by thread T(\[0-9\]+) >> here:.*(\n|\r\n|\r)" } >> +// { dg-output ".*WRITE of size 4 at 0x\[0-9a-f\]+ thread >> T(\[0-9\]+).*(\n|\r\n|\r)" } >> +// { dg-output ".*freed by thread T(\[0-9\]+) here:.*(\n|\r\n|\r)" } >> +// { dg-output ".*previously allocated by thread T(\[0-9\]+) >> here:.*(\n|\r\n|\r)" } >> // { dg-output "Thread T\\2 created by T(\[0-9\]+) here:.*(\n|\r\n|\r)" } >> // { dg-output "Thread T\\8 created by T0 here:.*(\n|\r\n|\r)" } >> // { dg-output "Thread T\\4 created by T(\[0-9\]+) here:.*(\n|\r\n|\r)" } >> diff --git a/gcc/testsuite/g++.dg/asan/large-func-test-1.C >> b/gcc/testsuite/g++.dg/asan/large-func-test-1.C >> index 32808e7..0d5c383 100644 >> --- a/gcc/testsuite/g++.dg/asan/large-func-test-1.C >> +++ b/gcc/testsuite/g++.dg/asan/large-func-test-1.C >> @@ -37,9 +37,9 @@ int main() { >> >> // { dg-output "ERROR: AddressSanitizer:? heap-buffer-overflow 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 "READ of size 4 at 0x\[0-9a-f\]+ thread >> T0\[^\n\r]*(\n|\r\n|\r)" } >> +// { dg-output ".*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 >> \[^\n\r]*LargeFunction\[^\n\r]*(large-func-test-1.C:18|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" >> } >> -// { dg-output "0x\[0-9a-f\]+ is located 44 bytes to the right of >> 400-byte region.*(\n|\r\n|\r)" } >> -// { dg-output "allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } >> +// { dg-output ".*0x\[0-9a-f\]+ is located 44 bytes to the right of >> 400-byte region.*(\n|\r\n|\r)" } >> +// { dg-output ".*allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } >> // { dg-output " #0( 0x\[0-9a-f\]+ (in >> _*(interceptor_|)malloc|\[(\])\[^\n\r]*(\n|\r\n|\r)" } >> // { dg-output " #1|) 0x\[0-9a-f\]+ (in (operator >> new|_*_Zn\[aw\]\[mj\])|\[(\])\[^\n\r]*(\n|\r\n|\r)" } >> diff --git a/gcc/testsuite/lib/target-supports.exp >> b/gcc/testsuite/lib/target-supports.exp >> index 45c8b84..28b6b6d 100644 >> --- a/gcc/testsuite/lib/target-supports.exp >> +++ b/gcc/testsuite/lib/target-supports.exp >> @@ -4668,6 +4668,33 @@ proc check_effective_target_simulator { } { >> return 0 >> } >> >> +# Return 1 if programs are intended to be run on hardware rather than >> +# on a simulator >> + >> +proc check_effective_target_hw { } { >> + >> + # All "src/sim" simulators set this one. >> + if [board_info target exists is_simulator] { >> + if [board_info target is_simulator] { >> + return 0 >> + } else { >> + return 1 >> + } >> + } >> + >> + # The "sid" simulators don't set that one, but at least they set >> + # this one. >> + if [board_info target exists slow_simulator] { >> + if [board_info target slow_simulator] { >> + return 0 >> + } else { >> + return 1 >> + } >> + } >> + >> + return 1 >> +} >> + >> # Return 1 if the target is a VxWorks kernel. >> >> proc check_effective_target_vxworks_kernel { } { >> diff --git a/libsanitizer/configure.tgt b/libsanitizer/configure.tgt >> index 265da01..bdfc22e 100644 >> --- a/libsanitizer/configure.tgt >> +++ b/libsanitizer/configure.tgt >> @@ -29,6 +29,8 @@ case "${target}" in >> ;; >> sparc*-*-linux*) >> ;; >> + arm*-*-linux*) >> + ;; >> x86_64-*-darwin[1]* | i?86-*-darwin[1]*) >> TSAN_SUPPORTED=no >> ;; >> diff --git a/libsanitizer/sanitizer_common/sanitizer_stacktrace.cc >> b/libsanitizer/sanitizer_common/sanitizer_stacktrace.cc >> index e14ea44..7b3e4ca 100644 >> --- a/libsanitizer/sanitizer_common/sanitizer_stacktrace.cc >> +++ b/libsanitizer/sanitizer_common/sanitizer_stacktrace.cc >> @@ -27,7 +27,7 @@ const char *StripPathPrefix(const char *filepath, >> uptr StackTrace::GetPreviousInstructionPc(uptr pc) { >> #ifdef __arm__ >> // Cancel Thumb bit. >> - pc = pc & (~1); >> + return pc & (~1); Here you are cancelling "pc - 1" operation, why? It is needed for the function to return the address of the _previous_ instruction. It matters when the call instruction is the last one in a function (because the callee is no-return), and return address is actually outside the function. >> #endif >> #if defined(__powerpc__) || defined(__powerpc64__) >> // PCs are always 4 byte aligned.
Oops, you are correct, I read the code too quickly and didn't notice the #endif right after the Thumb bit cancellation (I thought the function didn't return any value when on ARM). A white line before #if defined(__powerpc__) would help readability :-) Forget that part. Thanks, Christophe. On 7 May 2013 09:44, Evgeniy Stepanov <eugenis@google.com> wrote: > On Tue, May 7, 2013 at 9:33 AM, Konstantin Serebryany > <konstantin.s.serebryany@gmail.com> wrote: >> +eugenis@google.com (our ARM expert) >> >> Christophe, >> >> The change in sanitizer_common/sanitizer_stacktrace.cc changes the >> logic which is known to work well for us on Android/ARM. >> I'd like Evgeniy to comment on it. >> >> --kcc >> >> On Mon, May 6, 2013 at 10:52 PM, Christophe Lyon >> <christophe.lyon@linaro.org> wrote: >>> Hi, >>> >>> Here is a 2nd attempt at enabling libsanitizer on ARM. >>> Compared with the previous version, this patch is more intrusive to >>> workaround some limitations with qemu: >>> >>> * qemu does not work well with threads, so I chose to disable >>> clone-test-1.c and rlimit-mmap-test-1.c when running on a simulator. >>> This is a bit overkill since the limitation is caused by qemu, not by >>> the fact of running on a simulator. Would it cause problems on other >>> targets? >>> >>> * due to different connexion mathod between runtest and the target >>> program in native mode and in simulated mode, causing isatty(2) to >>> give a different answer, I modified a few regexps to accept possible >>> decorations. This can be removed once ASAN_OPTIONS=color=0 is >>> implemented. >>> >>> Tested on x86 with no regression, on ARM cortex-a9 hardware and >>> a15-qemu with the expected new tests. >>> >>> OK? >>> >>> Christophe. >>> >>> 2013-05-06 Christophe Lyon <christophe.lyon@linaro.org> >>> >>> gcc/ >>> * config/arm/arm.c (arm_asan_shadow_offset): New function. >>> (TARGET_ASAN_SHADOW_OFFSET): Define. >>> * config/arm/linux-eabi.h (ASAN_CC1_SPEC): Define. >>> (LINUX_OR_ANDROID_CC): Add ASAN_CC1_SPEC. >>> >>> libsanitizer/ >>> * configure.tgt: Add ARM pattern. >>> * sanitizer_common/sanitizer_stacktrace.cc: Return the computed >>> value. >>> >>> testsuite/ >>> * lib/target-supports.exp (check_effective_target_hw): New >>> function. >>> * c-c++-common/asan/clone-test-1.c: Call >>> check_effective_target_hw. >>> * c-c++-common/asan/rlimit-mmap-test-1.c: Likewise. >>> * c-c++-common/asan/heap-overflow-1.c: Update regexps to accept >>> possible decorations. >>> * c-c++-common/asan/null-deref-1.c: Likewise. >>> * c-c++-common/asan/stack-overflow-1.c: Likewise. >>> * c-c++-common/asan/strncpy-overflow-1.c: Likewise. >>> * c-c++-common/asan/use-after-free-1.c: Likewise. >>> * g++.dg/asan/deep-thread-stack-1.C: Likewise. >>> * g++.dg/asan/large-func-test-1.C: Likewise. >>> >>> diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c >>> index 0b97cf8..c036a21 100644 >>> --- a/gcc/config/arm/arm.c >>> +++ b/gcc/config/arm/arm.c >>> @@ -281,6 +281,8 @@ static unsigned arm_add_stmt_cost (void *data, int count, >>> >>> static void arm_canonicalize_comparison (int *code, rtx *op0, rtx *op1, >>> bool op0_preserve_value); >>> +static unsigned HOST_WIDE_INT arm_asan_shadow_offset (void); >>> + >>> >>> /* Table of machine attributes. */ >>> static const struct attribute_spec arm_attribute_table[] = >>> @@ -657,6 +659,9 @@ static const struct attribute_spec arm_attribute_table[] = >>> #define TARGET_CANONICALIZE_COMPARISON \ >>> arm_canonicalize_comparison >>> >>> +#undef TARGET_ASAN_SHADOW_OFFSET >>> +#define TARGET_ASAN_SHADOW_OFFSET arm_asan_shadow_offset >>> + >>> struct gcc_target targetm = TARGET_INITIALIZER; >>> >>> /* Obstack for minipool constant handling. */ >>> @@ -28062,4 +28067,12 @@ arm_validize_comparison (rtx *comparison, rtx >>> * op1, rtx * op2) >>> >>> } >>> >>> +/* Implement the TARGET_ASAN_SHADOW_OFFSET hook. */ >>> + >>> +static unsigned HOST_WIDE_INT >>> +arm_asan_shadow_offset (void) >>> +{ >>> + return (unsigned HOST_WIDE_INT) 1 << 29; >>> +} >>> + >>> #include "gt-arm.h" >>> diff --git a/gcc/config/arm/linux-eabi.h b/gcc/config/arm/linux-eabi.h >>> index 23671a7..cb0aad1 100644 >>> --- a/gcc/config/arm/linux-eabi.h >>> +++ b/gcc/config/arm/linux-eabi.h >>> @@ -84,10 +84,14 @@ >>> LINUX_OR_ANDROID_LD (LINUX_TARGET_LINK_SPEC, \ >>> LINUX_TARGET_LINK_SPEC " " ANDROID_LINK_SPEC) >>> >>> +#undef ASAN_CC1_SPEC >>> +#define ASAN_CC1_SPEC "%{fsanitize=*:-funwind-tables}" >>> + >>> #undef CC1_SPEC >>> #define CC1_SPEC \ >>> - LINUX_OR_ANDROID_CC (GNU_USER_TARGET_CC1_SPEC, \ >>> - GNU_USER_TARGET_CC1_SPEC " " ANDROID_CC1_SPEC) >>> + LINUX_OR_ANDROID_CC (GNU_USER_TARGET_CC1_SPEC " " ASAN_CC1_SPEC, \ >>> + GNU_USER_TARGET_CC1_SPEC " " ASAN_CC1_SPEC " " \ >>> + ANDROID_CC1_SPEC) >>> >>> #define CC1PLUS_SPEC \ >>> LINUX_OR_ANDROID_CC ("", ANDROID_CC1PLUS_SPEC) >>> diff --git a/gcc/testsuite/c-c++-common/asan/clone-test-1.c >>> b/gcc/testsuite/c-c++-common/asan/clone-test-1.c >>> index d9acc0d..fd187aa 100644 >>> --- a/gcc/testsuite/c-c++-common/asan/clone-test-1.c >>> +++ b/gcc/testsuite/c-c++-common/asan/clone-test-1.c >>> @@ -3,6 +3,7 @@ >>> >>> /* { dg-do run { target { *-*-linux* } } } */ >>> /* { dg-require-effective-target clone } */ >>> +/* { dg-require-effective-target hw } */ >>> /* { dg-options "-D_GNU_SOURCE" } */ >>> >>> #include <stdio.h> >>> diff --git a/gcc/testsuite/c-c++-common/asan/heap-overflow-1.c >>> b/gcc/testsuite/c-c++-common/asan/heap-overflow-1.c >>> index 43d47a3..e0b9038 100644 >>> --- a/gcc/testsuite/c-c++-common/asan/heap-overflow-1.c >>> +++ b/gcc/testsuite/c-c++-common/asan/heap-overflow-1.c >>> @@ -25,7 +25,7 @@ int main(int argc, char **argv) { >>> >>> /* { dg-output "READ of size 1 at 0x\[0-9a-f\]+ thread T0.*(\n|\r\n|\r)" } */ >>> /* { dg-output " #0 0x\[0-9a-f\]+ (in _*main >>> (\[^\n\r]*heap-overflow-1.c:21|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } */ >>> -/* { dg-output "0x\[0-9a-f\]+ is located 0 bytes to the right of >>> 10-byte region\[^\n\r]*(\n|\r\n|\r)" } */ >>> -/* { dg-output "allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */ >>> +/* { dg-output ".*0x\[0-9a-f\]+ is located 0 bytes to the right of >>> 10-byte region\[^\n\r]*(\n|\r\n|\r)" } */ >>> +/* { dg-output ".*allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */ >>> /* { dg-output " #0 0x\[0-9a-f\]+ (in >>> _*(interceptor_|)malloc|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ >>> /* { dg-output " #1 0x\[0-9a-f\]+ (in _*main >>> (\[^\n\r]*heap-overflow-1.c:19|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" >>> } */ >>> diff --git a/gcc/testsuite/c-c++-common/asan/null-deref-1.c >>> b/gcc/testsuite/c-c++-common/asan/null-deref-1.c >>> index 2eee986..95e5036 100644 >>> --- a/gcc/testsuite/c-c++-common/asan/null-deref-1.c >>> +++ b/gcc/testsuite/c-c++-common/asan/null-deref-1.c >>> @@ -18,6 +18,6 @@ int main() >>> >>> /* { dg-output "ERROR: AddressSanitizer:? SEGV on unknown >>> address\[^\n\r]*" } */ >>> /* { dg-output "0x\[0-9a-f\]+ \[^\n\r]*pc >>> 0x\[0-9a-f\]+\[^\n\r]*(\n|\r\n|\r)" } */ >>> -/* { dg-output "AddressSanitizer can not provide additional >>> info.*(\n|\r\n|\r)" } */ >>> +/* { dg-output ".*AddressSanitizer can not provide additional >>> info.*(\n|\r\n|\r)" } */ >>> /* { dg-output " #0 0x\[0-9a-f\]+ (in \[^\n\r]*NullDeref\[^\n\r]* >>> (\[^\n\r]*null-deref-1.c:10|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" >>> } */ >>> /* { dg-output " #1 0x\[0-9a-f\]+ (in _*main >>> (\[^\n\r]*null-deref-1.c:15|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" >>> } */ >>> diff --git a/gcc/testsuite/c-c++-common/asan/rlimit-mmap-test-1.c >>> b/gcc/testsuite/c-c++-common/asan/rlimit-mmap-test-1.c >>> index 0b3d2ae..9dbbc85 100644 >>> --- a/gcc/testsuite/c-c++-common/asan/rlimit-mmap-test-1.c >>> +++ b/gcc/testsuite/c-c++-common/asan/rlimit-mmap-test-1.c >>> @@ -2,6 +2,7 @@ >>> >>> /* { dg-do run { target setrlimit } } */ >>> /* { dg-skip-if "" { *-*-* } { "*" } { "-O0" } } */ >>> +/* { dg-require-effective-target hw } */ >>> /* { dg-shouldfail "asan" } */ >>> >>> #include <stdlib.h> >>> diff --git a/gcc/testsuite/c-c++-common/asan/stack-overflow-1.c >>> b/gcc/testsuite/c-c++-common/asan/stack-overflow-1.c >>> index 790aa5e..5788b10 100644 >>> --- a/gcc/testsuite/c-c++-common/asan/stack-overflow-1.c >>> +++ b/gcc/testsuite/c-c++-common/asan/stack-overflow-1.c >>> @@ -19,4 +19,4 @@ int main() { >>> >>> /* { dg-output "READ of size 1 at 0x\[0-9a-f\]+ thread >>> T0\[^\n\r]*(\n|\r\n|\r)" } */ >>> /* { dg-output " #0 0x\[0-9a-f\]+ (in _*main >>> (\[^\n\r]*stack-overflow-1.c:16|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } >>> */ >>> -/* { dg-output "Address 0x\[0-9a-f\]+ is\[^\n\r]*frame <main>" } */ >>> +/* { dg-output ".*Address 0x\[0-9a-f\]+ is\[^\n\r]*frame <main>" } */ >>> diff --git a/gcc/testsuite/c-c++-common/asan/strncpy-overflow-1.c >>> b/gcc/testsuite/c-c++-common/asan/strncpy-overflow-1.c >>> index 10b3ad7..5e8ce40 100644 >>> --- a/gcc/testsuite/c-c++-common/asan/strncpy-overflow-1.c >>> +++ b/gcc/testsuite/c-c++-common/asan/strncpy-overflow-1.c >>> @@ -15,7 +15,7 @@ int main(int argc, char **argv) { >>> /* { dg-output "WRITE of size \[0-9\]* at 0x\[0-9a-f\]+ thread >>> T0\[^\n\r]*(\n|\r\n|\r)" } */ >>> /* { dg-output " #0 0x\[0-9a-f\]+ (in >>> _*(interceptor_|)strncpy|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ >>> /* { dg-output " #1 0x\[0-9a-f\]+ (in _*main >>> (\[^\n\r]*strncpy-overflow-1.c:11|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } >>> */ >>> -/* { dg-output "0x\[0-9a-f\]+ is located 0 bytes to the right of >>> 9-byte region\[^\n\r]*(\n|\r\n|\r)" } */ >>> -/* { dg-output "allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */ >>> +/* { dg-output ".*0x\[0-9a-f\]+ is located 0 bytes to the right of >>> 9-byte region\[^\n\r]*(\n|\r\n|\r)" } */ >>> +/* { dg-output ".*allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */ >>> /* { dg-output " #0 0x\[0-9a-f\]+ (in >>> _*(interceptor_|)malloc|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ >>> /* { dg-output " #1 0x\[0-9a-f\]+ (in _*main >>> (\[^\n\r]*strncpy-overflow-1.c:10|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" >>> } */ >>> diff --git a/gcc/testsuite/c-c++-common/asan/use-after-free-1.c >>> b/gcc/testsuite/c-c++-common/asan/use-after-free-1.c >>> index 939feeb..65318c8 100644 >>> --- a/gcc/testsuite/c-c++-common/asan/use-after-free-1.c >>> +++ b/gcc/testsuite/c-c++-common/asan/use-after-free-1.c >>> @@ -11,12 +11,12 @@ int main() { >>> >>> /* { dg-output "ERROR: AddressSanitizer:? heap-use-after-free 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 "READ of size 1 at 0x\[0-9a-f\]+ thread >>> T0\[^\n\r]*(\n|\r\n|\r)" } */ >>> +/* { dg-output ".*READ of size 1 at 0x\[0-9a-f\]+ thread >>> T0\[^\n\r]*(\n|\r\n|\r)" } */ >>> /* { dg-output " #0 0x\[0-9a-f\]+ (in _*main >>> (\[^\n\r]*use-after-free-1.c:9|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } */ >>> -/* { dg-output "0x\[0-9a-f\]+ is located 5 bytes inside of 10-byte >>> region .0x\[0-9a-f\]+,0x\[0-9a-f\]+\[^\n\r]*(\n|\r\n|\r)" } */ >>> -/* { dg-output "freed by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */ >>> +/* { dg-output ".*0x\[0-9a-f\]+ is located 5 bytes inside of 10-byte >>> region .0x\[0-9a-f\]+,0x\[0-9a-f\]+\[^\n\r]*(\n|\r\n|\r)" } */ >>> +/* { dg-output ".*freed by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */ >>> /* { dg-output " #0 0x\[0-9a-f\]+ (in >>> _*(interceptor_|)free|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ >>> /* { dg-output " #1 0x\[0-9a-f\]+ (in _*main >>> (\[^\n\r]*use-after-free-1.c:8|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } */ >>> -/* { dg-output "previously allocated by thread T0 >>> here:\[^\n\r]*(\n|\r\n|\r)" } */ >>> +/* { dg-output ".*previously allocated by thread T0 >>> here:\[^\n\r]*(\n|\r\n|\r)" } */ >>> /* { dg-output " #0 0x\[0-9a-f\]+ (in >>> _*(interceptor_|)malloc|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ >>> /* { dg-output " #1 0x\[0-9a-f\]+ (in _*main >>> (\[^\n\r]*use-after-free-1.c:7|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" >>> } */ >>> diff --git a/gcc/testsuite/g++.dg/asan/deep-thread-stack-1.C >>> b/gcc/testsuite/g++.dg/asan/deep-thread-stack-1.C >>> index 12d8a7a..d29fe31 100644 >>> --- a/gcc/testsuite/g++.dg/asan/deep-thread-stack-1.C >>> +++ b/gcc/testsuite/g++.dg/asan/deep-thread-stack-1.C >>> @@ -45,9 +45,9 @@ int main(int argc, char *argv[]) { >>> } >>> >>> // { dg-output "ERROR: AddressSanitizer: heap-use-after-free.*(\n|\r\n|\r)" } >>> -// { dg-output "WRITE of size 4 at 0x\[0-9a-f\]+ thread >>> T(\[0-9\]+).*(\n|\r\n|\r)" } >>> -// { dg-output "freed by thread T(\[0-9\]+) here:.*(\n|\r\n|\r)" } >>> -// { dg-output "previously allocated by thread T(\[0-9\]+) >>> here:.*(\n|\r\n|\r)" } >>> +// { dg-output ".*WRITE of size 4 at 0x\[0-9a-f\]+ thread >>> T(\[0-9\]+).*(\n|\r\n|\r)" } >>> +// { dg-output ".*freed by thread T(\[0-9\]+) here:.*(\n|\r\n|\r)" } >>> +// { dg-output ".*previously allocated by thread T(\[0-9\]+) >>> here:.*(\n|\r\n|\r)" } >>> // { dg-output "Thread T\\2 created by T(\[0-9\]+) here:.*(\n|\r\n|\r)" } >>> // { dg-output "Thread T\\8 created by T0 here:.*(\n|\r\n|\r)" } >>> // { dg-output "Thread T\\4 created by T(\[0-9\]+) here:.*(\n|\r\n|\r)" } >>> diff --git a/gcc/testsuite/g++.dg/asan/large-func-test-1.C >>> b/gcc/testsuite/g++.dg/asan/large-func-test-1.C >>> index 32808e7..0d5c383 100644 >>> --- a/gcc/testsuite/g++.dg/asan/large-func-test-1.C >>> +++ b/gcc/testsuite/g++.dg/asan/large-func-test-1.C >>> @@ -37,9 +37,9 @@ int main() { >>> >>> // { dg-output "ERROR: AddressSanitizer:? heap-buffer-overflow 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 "READ of size 4 at 0x\[0-9a-f\]+ thread >>> T0\[^\n\r]*(\n|\r\n|\r)" } >>> +// { dg-output ".*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 >>> \[^\n\r]*LargeFunction\[^\n\r]*(large-func-test-1.C:18|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" >>> } >>> -// { dg-output "0x\[0-9a-f\]+ is located 44 bytes to the right of >>> 400-byte region.*(\n|\r\n|\r)" } >>> -// { dg-output "allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } >>> +// { dg-output ".*0x\[0-9a-f\]+ is located 44 bytes to the right of >>> 400-byte region.*(\n|\r\n|\r)" } >>> +// { dg-output ".*allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } >>> // { dg-output " #0( 0x\[0-9a-f\]+ (in >>> _*(interceptor_|)malloc|\[(\])\[^\n\r]*(\n|\r\n|\r)" } >>> // { dg-output " #1|) 0x\[0-9a-f\]+ (in (operator >>> new|_*_Zn\[aw\]\[mj\])|\[(\])\[^\n\r]*(\n|\r\n|\r)" } >>> diff --git a/gcc/testsuite/lib/target-supports.exp >>> b/gcc/testsuite/lib/target-supports.exp >>> index 45c8b84..28b6b6d 100644 >>> --- a/gcc/testsuite/lib/target-supports.exp >>> +++ b/gcc/testsuite/lib/target-supports.exp >>> @@ -4668,6 +4668,33 @@ proc check_effective_target_simulator { } { >>> return 0 >>> } >>> >>> +# Return 1 if programs are intended to be run on hardware rather than >>> +# on a simulator >>> + >>> +proc check_effective_target_hw { } { >>> + >>> + # All "src/sim" simulators set this one. >>> + if [board_info target exists is_simulator] { >>> + if [board_info target is_simulator] { >>> + return 0 >>> + } else { >>> + return 1 >>> + } >>> + } >>> + >>> + # The "sid" simulators don't set that one, but at least they set >>> + # this one. >>> + if [board_info target exists slow_simulator] { >>> + if [board_info target slow_simulator] { >>> + return 0 >>> + } else { >>> + return 1 >>> + } >>> + } >>> + >>> + return 1 >>> +} >>> + >>> # Return 1 if the target is a VxWorks kernel. >>> >>> proc check_effective_target_vxworks_kernel { } { >>> diff --git a/libsanitizer/configure.tgt b/libsanitizer/configure.tgt >>> index 265da01..bdfc22e 100644 >>> --- a/libsanitizer/configure.tgt >>> +++ b/libsanitizer/configure.tgt >>> @@ -29,6 +29,8 @@ case "${target}" in >>> ;; >>> sparc*-*-linux*) >>> ;; >>> + arm*-*-linux*) >>> + ;; >>> x86_64-*-darwin[1]* | i?86-*-darwin[1]*) >>> TSAN_SUPPORTED=no >>> ;; >>> diff --git a/libsanitizer/sanitizer_common/sanitizer_stacktrace.cc >>> b/libsanitizer/sanitizer_common/sanitizer_stacktrace.cc >>> index e14ea44..7b3e4ca 100644 >>> --- a/libsanitizer/sanitizer_common/sanitizer_stacktrace.cc >>> +++ b/libsanitizer/sanitizer_common/sanitizer_stacktrace.cc >>> @@ -27,7 +27,7 @@ const char *StripPathPrefix(const char *filepath, >>> uptr StackTrace::GetPreviousInstructionPc(uptr pc) { >>> #ifdef __arm__ >>> // Cancel Thumb bit. >>> - pc = pc & (~1); >>> + return pc & (~1); > > Here you are cancelling "pc - 1" operation, why? It is needed for the > function to return the address of the _previous_ instruction. It > matters when the call instruction is the last one in a function > (because the callee is no-return), and return address is actually > outside the function. > >>> #endif >>> #if defined(__powerpc__) || defined(__powerpc64__) >>> // PCs are always 4 byte aligned.
The rest of the patch is gcc-specific. Jakub? On Tue, May 7, 2013 at 12:12 PM, Christophe Lyon <christophe.lyon@linaro.org> wrote: > Oops, you are correct, I read the code too quickly and didn't notice > the #endif right after the Thumb bit cancellation (I thought the > function didn't return any value when on ARM). > > A white line before #if defined(__powerpc__) would help readability :-) > > Forget that part. > > Thanks, > > Christophe. > > > > > On 7 May 2013 09:44, Evgeniy Stepanov <eugenis@google.com> wrote: >> On Tue, May 7, 2013 at 9:33 AM, Konstantin Serebryany >> <konstantin.s.serebryany@gmail.com> wrote: >>> +eugenis@google.com (our ARM expert) >>> >>> Christophe, >>> >>> The change in sanitizer_common/sanitizer_stacktrace.cc changes the >>> logic which is known to work well for us on Android/ARM. >>> I'd like Evgeniy to comment on it. >>> >>> --kcc >>> >>> On Mon, May 6, 2013 at 10:52 PM, Christophe Lyon >>> <christophe.lyon@linaro.org> wrote: >>>> Hi, >>>> >>>> Here is a 2nd attempt at enabling libsanitizer on ARM. >>>> Compared with the previous version, this patch is more intrusive to >>>> workaround some limitations with qemu: >>>> >>>> * qemu does not work well with threads, so I chose to disable >>>> clone-test-1.c and rlimit-mmap-test-1.c when running on a simulator. >>>> This is a bit overkill since the limitation is caused by qemu, not by >>>> the fact of running on a simulator. Would it cause problems on other >>>> targets? >>>> >>>> * due to different connexion mathod between runtest and the target >>>> program in native mode and in simulated mode, causing isatty(2) to >>>> give a different answer, I modified a few regexps to accept possible >>>> decorations. This can be removed once ASAN_OPTIONS=color=0 is >>>> implemented. >>>> >>>> Tested on x86 with no regression, on ARM cortex-a9 hardware and >>>> a15-qemu with the expected new tests. >>>> >>>> OK? >>>> >>>> Christophe. >>>> >>>> 2013-05-06 Christophe Lyon <christophe.lyon@linaro.org> >>>> >>>> gcc/ >>>> * config/arm/arm.c (arm_asan_shadow_offset): New function. >>>> (TARGET_ASAN_SHADOW_OFFSET): Define. >>>> * config/arm/linux-eabi.h (ASAN_CC1_SPEC): Define. >>>> (LINUX_OR_ANDROID_CC): Add ASAN_CC1_SPEC. >>>> >>>> libsanitizer/ >>>> * configure.tgt: Add ARM pattern. >>>> * sanitizer_common/sanitizer_stacktrace.cc: Return the computed >>>> value. >>>> >>>> testsuite/ >>>> * lib/target-supports.exp (check_effective_target_hw): New >>>> function. >>>> * c-c++-common/asan/clone-test-1.c: Call >>>> check_effective_target_hw. >>>> * c-c++-common/asan/rlimit-mmap-test-1.c: Likewise. >>>> * c-c++-common/asan/heap-overflow-1.c: Update regexps to accept >>>> possible decorations. >>>> * c-c++-common/asan/null-deref-1.c: Likewise. >>>> * c-c++-common/asan/stack-overflow-1.c: Likewise. >>>> * c-c++-common/asan/strncpy-overflow-1.c: Likewise. >>>> * c-c++-common/asan/use-after-free-1.c: Likewise. >>>> * g++.dg/asan/deep-thread-stack-1.C: Likewise. >>>> * g++.dg/asan/large-func-test-1.C: Likewise. >>>> >>>> diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c >>>> index 0b97cf8..c036a21 100644 >>>> --- a/gcc/config/arm/arm.c >>>> +++ b/gcc/config/arm/arm.c >>>> @@ -281,6 +281,8 @@ static unsigned arm_add_stmt_cost (void *data, int count, >>>> >>>> static void arm_canonicalize_comparison (int *code, rtx *op0, rtx *op1, >>>> bool op0_preserve_value); >>>> +static unsigned HOST_WIDE_INT arm_asan_shadow_offset (void); >>>> + >>>> >>>> /* Table of machine attributes. */ >>>> static const struct attribute_spec arm_attribute_table[] = >>>> @@ -657,6 +659,9 @@ static const struct attribute_spec arm_attribute_table[] = >>>> #define TARGET_CANONICALIZE_COMPARISON \ >>>> arm_canonicalize_comparison >>>> >>>> +#undef TARGET_ASAN_SHADOW_OFFSET >>>> +#define TARGET_ASAN_SHADOW_OFFSET arm_asan_shadow_offset >>>> + >>>> struct gcc_target targetm = TARGET_INITIALIZER; >>>> >>>> /* Obstack for minipool constant handling. */ >>>> @@ -28062,4 +28067,12 @@ arm_validize_comparison (rtx *comparison, rtx >>>> * op1, rtx * op2) >>>> >>>> } >>>> >>>> +/* Implement the TARGET_ASAN_SHADOW_OFFSET hook. */ >>>> + >>>> +static unsigned HOST_WIDE_INT >>>> +arm_asan_shadow_offset (void) >>>> +{ >>>> + return (unsigned HOST_WIDE_INT) 1 << 29; >>>> +} >>>> + >>>> #include "gt-arm.h" >>>> diff --git a/gcc/config/arm/linux-eabi.h b/gcc/config/arm/linux-eabi.h >>>> index 23671a7..cb0aad1 100644 >>>> --- a/gcc/config/arm/linux-eabi.h >>>> +++ b/gcc/config/arm/linux-eabi.h >>>> @@ -84,10 +84,14 @@ >>>> LINUX_OR_ANDROID_LD (LINUX_TARGET_LINK_SPEC, \ >>>> LINUX_TARGET_LINK_SPEC " " ANDROID_LINK_SPEC) >>>> >>>> +#undef ASAN_CC1_SPEC >>>> +#define ASAN_CC1_SPEC "%{fsanitize=*:-funwind-tables}" >>>> + >>>> #undef CC1_SPEC >>>> #define CC1_SPEC \ >>>> - LINUX_OR_ANDROID_CC (GNU_USER_TARGET_CC1_SPEC, \ >>>> - GNU_USER_TARGET_CC1_SPEC " " ANDROID_CC1_SPEC) >>>> + LINUX_OR_ANDROID_CC (GNU_USER_TARGET_CC1_SPEC " " ASAN_CC1_SPEC, \ >>>> + GNU_USER_TARGET_CC1_SPEC " " ASAN_CC1_SPEC " " \ >>>> + ANDROID_CC1_SPEC) >>>> >>>> #define CC1PLUS_SPEC \ >>>> LINUX_OR_ANDROID_CC ("", ANDROID_CC1PLUS_SPEC) >>>> diff --git a/gcc/testsuite/c-c++-common/asan/clone-test-1.c >>>> b/gcc/testsuite/c-c++-common/asan/clone-test-1.c >>>> index d9acc0d..fd187aa 100644 >>>> --- a/gcc/testsuite/c-c++-common/asan/clone-test-1.c >>>> +++ b/gcc/testsuite/c-c++-common/asan/clone-test-1.c >>>> @@ -3,6 +3,7 @@ >>>> >>>> /* { dg-do run { target { *-*-linux* } } } */ >>>> /* { dg-require-effective-target clone } */ >>>> +/* { dg-require-effective-target hw } */ >>>> /* { dg-options "-D_GNU_SOURCE" } */ >>>> >>>> #include <stdio.h> >>>> diff --git a/gcc/testsuite/c-c++-common/asan/heap-overflow-1.c >>>> b/gcc/testsuite/c-c++-common/asan/heap-overflow-1.c >>>> index 43d47a3..e0b9038 100644 >>>> --- a/gcc/testsuite/c-c++-common/asan/heap-overflow-1.c >>>> +++ b/gcc/testsuite/c-c++-common/asan/heap-overflow-1.c >>>> @@ -25,7 +25,7 @@ int main(int argc, char **argv) { >>>> >>>> /* { dg-output "READ of size 1 at 0x\[0-9a-f\]+ thread T0.*(\n|\r\n|\r)" } */ >>>> /* { dg-output " #0 0x\[0-9a-f\]+ (in _*main >>>> (\[^\n\r]*heap-overflow-1.c:21|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } */ >>>> -/* { dg-output "0x\[0-9a-f\]+ is located 0 bytes to the right of >>>> 10-byte region\[^\n\r]*(\n|\r\n|\r)" } */ >>>> -/* { dg-output "allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */ >>>> +/* { dg-output ".*0x\[0-9a-f\]+ is located 0 bytes to the right of >>>> 10-byte region\[^\n\r]*(\n|\r\n|\r)" } */ >>>> +/* { dg-output ".*allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */ >>>> /* { dg-output " #0 0x\[0-9a-f\]+ (in >>>> _*(interceptor_|)malloc|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ >>>> /* { dg-output " #1 0x\[0-9a-f\]+ (in _*main >>>> (\[^\n\r]*heap-overflow-1.c:19|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" >>>> } */ >>>> diff --git a/gcc/testsuite/c-c++-common/asan/null-deref-1.c >>>> b/gcc/testsuite/c-c++-common/asan/null-deref-1.c >>>> index 2eee986..95e5036 100644 >>>> --- a/gcc/testsuite/c-c++-common/asan/null-deref-1.c >>>> +++ b/gcc/testsuite/c-c++-common/asan/null-deref-1.c >>>> @@ -18,6 +18,6 @@ int main() >>>> >>>> /* { dg-output "ERROR: AddressSanitizer:? SEGV on unknown >>>> address\[^\n\r]*" } */ >>>> /* { dg-output "0x\[0-9a-f\]+ \[^\n\r]*pc >>>> 0x\[0-9a-f\]+\[^\n\r]*(\n|\r\n|\r)" } */ >>>> -/* { dg-output "AddressSanitizer can not provide additional >>>> info.*(\n|\r\n|\r)" } */ >>>> +/* { dg-output ".*AddressSanitizer can not provide additional >>>> info.*(\n|\r\n|\r)" } */ >>>> /* { dg-output " #0 0x\[0-9a-f\]+ (in \[^\n\r]*NullDeref\[^\n\r]* >>>> (\[^\n\r]*null-deref-1.c:10|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" >>>> } */ >>>> /* { dg-output " #1 0x\[0-9a-f\]+ (in _*main >>>> (\[^\n\r]*null-deref-1.c:15|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" >>>> } */ >>>> diff --git a/gcc/testsuite/c-c++-common/asan/rlimit-mmap-test-1.c >>>> b/gcc/testsuite/c-c++-common/asan/rlimit-mmap-test-1.c >>>> index 0b3d2ae..9dbbc85 100644 >>>> --- a/gcc/testsuite/c-c++-common/asan/rlimit-mmap-test-1.c >>>> +++ b/gcc/testsuite/c-c++-common/asan/rlimit-mmap-test-1.c >>>> @@ -2,6 +2,7 @@ >>>> >>>> /* { dg-do run { target setrlimit } } */ >>>> /* { dg-skip-if "" { *-*-* } { "*" } { "-O0" } } */ >>>> +/* { dg-require-effective-target hw } */ >>>> /* { dg-shouldfail "asan" } */ >>>> >>>> #include <stdlib.h> >>>> diff --git a/gcc/testsuite/c-c++-common/asan/stack-overflow-1.c >>>> b/gcc/testsuite/c-c++-common/asan/stack-overflow-1.c >>>> index 790aa5e..5788b10 100644 >>>> --- a/gcc/testsuite/c-c++-common/asan/stack-overflow-1.c >>>> +++ b/gcc/testsuite/c-c++-common/asan/stack-overflow-1.c >>>> @@ -19,4 +19,4 @@ int main() { >>>> >>>> /* { dg-output "READ of size 1 at 0x\[0-9a-f\]+ thread >>>> T0\[^\n\r]*(\n|\r\n|\r)" } */ >>>> /* { dg-output " #0 0x\[0-9a-f\]+ (in _*main >>>> (\[^\n\r]*stack-overflow-1.c:16|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } >>>> */ >>>> -/* { dg-output "Address 0x\[0-9a-f\]+ is\[^\n\r]*frame <main>" } */ >>>> +/* { dg-output ".*Address 0x\[0-9a-f\]+ is\[^\n\r]*frame <main>" } */ >>>> diff --git a/gcc/testsuite/c-c++-common/asan/strncpy-overflow-1.c >>>> b/gcc/testsuite/c-c++-common/asan/strncpy-overflow-1.c >>>> index 10b3ad7..5e8ce40 100644 >>>> --- a/gcc/testsuite/c-c++-common/asan/strncpy-overflow-1.c >>>> +++ b/gcc/testsuite/c-c++-common/asan/strncpy-overflow-1.c >>>> @@ -15,7 +15,7 @@ int main(int argc, char **argv) { >>>> /* { dg-output "WRITE of size \[0-9\]* at 0x\[0-9a-f\]+ thread >>>> T0\[^\n\r]*(\n|\r\n|\r)" } */ >>>> /* { dg-output " #0 0x\[0-9a-f\]+ (in >>>> _*(interceptor_|)strncpy|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ >>>> /* { dg-output " #1 0x\[0-9a-f\]+ (in _*main >>>> (\[^\n\r]*strncpy-overflow-1.c:11|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } >>>> */ >>>> -/* { dg-output "0x\[0-9a-f\]+ is located 0 bytes to the right of >>>> 9-byte region\[^\n\r]*(\n|\r\n|\r)" } */ >>>> -/* { dg-output "allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */ >>>> +/* { dg-output ".*0x\[0-9a-f\]+ is located 0 bytes to the right of >>>> 9-byte region\[^\n\r]*(\n|\r\n|\r)" } */ >>>> +/* { dg-output ".*allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */ >>>> /* { dg-output " #0 0x\[0-9a-f\]+ (in >>>> _*(interceptor_|)malloc|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ >>>> /* { dg-output " #1 0x\[0-9a-f\]+ (in _*main >>>> (\[^\n\r]*strncpy-overflow-1.c:10|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" >>>> } */ >>>> diff --git a/gcc/testsuite/c-c++-common/asan/use-after-free-1.c >>>> b/gcc/testsuite/c-c++-common/asan/use-after-free-1.c >>>> index 939feeb..65318c8 100644 >>>> --- a/gcc/testsuite/c-c++-common/asan/use-after-free-1.c >>>> +++ b/gcc/testsuite/c-c++-common/asan/use-after-free-1.c >>>> @@ -11,12 +11,12 @@ int main() { >>>> >>>> /* { dg-output "ERROR: AddressSanitizer:? heap-use-after-free 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 "READ of size 1 at 0x\[0-9a-f\]+ thread >>>> T0\[^\n\r]*(\n|\r\n|\r)" } */ >>>> +/* { dg-output ".*READ of size 1 at 0x\[0-9a-f\]+ thread >>>> T0\[^\n\r]*(\n|\r\n|\r)" } */ >>>> /* { dg-output " #0 0x\[0-9a-f\]+ (in _*main >>>> (\[^\n\r]*use-after-free-1.c:9|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } */ >>>> -/* { dg-output "0x\[0-9a-f\]+ is located 5 bytes inside of 10-byte >>>> region .0x\[0-9a-f\]+,0x\[0-9a-f\]+\[^\n\r]*(\n|\r\n|\r)" } */ >>>> -/* { dg-output "freed by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */ >>>> +/* { dg-output ".*0x\[0-9a-f\]+ is located 5 bytes inside of 10-byte >>>> region .0x\[0-9a-f\]+,0x\[0-9a-f\]+\[^\n\r]*(\n|\r\n|\r)" } */ >>>> +/* { dg-output ".*freed by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */ >>>> /* { dg-output " #0 0x\[0-9a-f\]+ (in >>>> _*(interceptor_|)free|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ >>>> /* { dg-output " #1 0x\[0-9a-f\]+ (in _*main >>>> (\[^\n\r]*use-after-free-1.c:8|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } */ >>>> -/* { dg-output "previously allocated by thread T0 >>>> here:\[^\n\r]*(\n|\r\n|\r)" } */ >>>> +/* { dg-output ".*previously allocated by thread T0 >>>> here:\[^\n\r]*(\n|\r\n|\r)" } */ >>>> /* { dg-output " #0 0x\[0-9a-f\]+ (in >>>> _*(interceptor_|)malloc|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ >>>> /* { dg-output " #1 0x\[0-9a-f\]+ (in _*main >>>> (\[^\n\r]*use-after-free-1.c:7|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" >>>> } */ >>>> diff --git a/gcc/testsuite/g++.dg/asan/deep-thread-stack-1.C >>>> b/gcc/testsuite/g++.dg/asan/deep-thread-stack-1.C >>>> index 12d8a7a..d29fe31 100644 >>>> --- a/gcc/testsuite/g++.dg/asan/deep-thread-stack-1.C >>>> +++ b/gcc/testsuite/g++.dg/asan/deep-thread-stack-1.C >>>> @@ -45,9 +45,9 @@ int main(int argc, char *argv[]) { >>>> } >>>> >>>> // { dg-output "ERROR: AddressSanitizer: heap-use-after-free.*(\n|\r\n|\r)" } >>>> -// { dg-output "WRITE of size 4 at 0x\[0-9a-f\]+ thread >>>> T(\[0-9\]+).*(\n|\r\n|\r)" } >>>> -// { dg-output "freed by thread T(\[0-9\]+) here:.*(\n|\r\n|\r)" } >>>> -// { dg-output "previously allocated by thread T(\[0-9\]+) >>>> here:.*(\n|\r\n|\r)" } >>>> +// { dg-output ".*WRITE of size 4 at 0x\[0-9a-f\]+ thread >>>> T(\[0-9\]+).*(\n|\r\n|\r)" } >>>> +// { dg-output ".*freed by thread T(\[0-9\]+) here:.*(\n|\r\n|\r)" } >>>> +// { dg-output ".*previously allocated by thread T(\[0-9\]+) >>>> here:.*(\n|\r\n|\r)" } >>>> // { dg-output "Thread T\\2 created by T(\[0-9\]+) here:.*(\n|\r\n|\r)" } >>>> // { dg-output "Thread T\\8 created by T0 here:.*(\n|\r\n|\r)" } >>>> // { dg-output "Thread T\\4 created by T(\[0-9\]+) here:.*(\n|\r\n|\r)" } >>>> diff --git a/gcc/testsuite/g++.dg/asan/large-func-test-1.C >>>> b/gcc/testsuite/g++.dg/asan/large-func-test-1.C >>>> index 32808e7..0d5c383 100644 >>>> --- a/gcc/testsuite/g++.dg/asan/large-func-test-1.C >>>> +++ b/gcc/testsuite/g++.dg/asan/large-func-test-1.C >>>> @@ -37,9 +37,9 @@ int main() { >>>> >>>> // { dg-output "ERROR: AddressSanitizer:? heap-buffer-overflow 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 "READ of size 4 at 0x\[0-9a-f\]+ thread >>>> T0\[^\n\r]*(\n|\r\n|\r)" } >>>> +// { dg-output ".*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 >>>> \[^\n\r]*LargeFunction\[^\n\r]*(large-func-test-1.C:18|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" >>>> } >>>> -// { dg-output "0x\[0-9a-f\]+ is located 44 bytes to the right of >>>> 400-byte region.*(\n|\r\n|\r)" } >>>> -// { dg-output "allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } >>>> +// { dg-output ".*0x\[0-9a-f\]+ is located 44 bytes to the right of >>>> 400-byte region.*(\n|\r\n|\r)" } >>>> +// { dg-output ".*allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } >>>> // { dg-output " #0( 0x\[0-9a-f\]+ (in >>>> _*(interceptor_|)malloc|\[(\])\[^\n\r]*(\n|\r\n|\r)" } >>>> // { dg-output " #1|) 0x\[0-9a-f\]+ (in (operator >>>> new|_*_Zn\[aw\]\[mj\])|\[(\])\[^\n\r]*(\n|\r\n|\r)" } >>>> diff --git a/gcc/testsuite/lib/target-supports.exp >>>> b/gcc/testsuite/lib/target-supports.exp >>>> index 45c8b84..28b6b6d 100644 >>>> --- a/gcc/testsuite/lib/target-supports.exp >>>> +++ b/gcc/testsuite/lib/target-supports.exp >>>> @@ -4668,6 +4668,33 @@ proc check_effective_target_simulator { } { >>>> return 0 >>>> } >>>> >>>> +# Return 1 if programs are intended to be run on hardware rather than >>>> +# on a simulator >>>> + >>>> +proc check_effective_target_hw { } { >>>> + >>>> + # All "src/sim" simulators set this one. >>>> + if [board_info target exists is_simulator] { >>>> + if [board_info target is_simulator] { >>>> + return 0 >>>> + } else { >>>> + return 1 >>>> + } >>>> + } >>>> + >>>> + # The "sid" simulators don't set that one, but at least they set >>>> + # this one. >>>> + if [board_info target exists slow_simulator] { >>>> + if [board_info target slow_simulator] { >>>> + return 0 >>>> + } else { >>>> + return 1 >>>> + } >>>> + } >>>> + >>>> + return 1 >>>> +} >>>> + >>>> # Return 1 if the target is a VxWorks kernel. >>>> >>>> proc check_effective_target_vxworks_kernel { } { >>>> diff --git a/libsanitizer/configure.tgt b/libsanitizer/configure.tgt >>>> index 265da01..bdfc22e 100644 >>>> --- a/libsanitizer/configure.tgt >>>> +++ b/libsanitizer/configure.tgt >>>> @@ -29,6 +29,8 @@ case "${target}" in >>>> ;; >>>> sparc*-*-linux*) >>>> ;; >>>> + arm*-*-linux*) >>>> + ;; >>>> x86_64-*-darwin[1]* | i?86-*-darwin[1]*) >>>> TSAN_SUPPORTED=no >>>> ;; >>>> diff --git a/libsanitizer/sanitizer_common/sanitizer_stacktrace.cc >>>> b/libsanitizer/sanitizer_common/sanitizer_stacktrace.cc >>>> index e14ea44..7b3e4ca 100644 >>>> --- a/libsanitizer/sanitizer_common/sanitizer_stacktrace.cc >>>> +++ b/libsanitizer/sanitizer_common/sanitizer_stacktrace.cc >>>> @@ -27,7 +27,7 @@ const char *StripPathPrefix(const char *filepath, >>>> uptr StackTrace::GetPreviousInstructionPc(uptr pc) { >>>> #ifdef __arm__ >>>> // Cancel Thumb bit. >>>> - pc = pc & (~1); >>>> + return pc & (~1); >> >> Here you are cancelling "pc - 1" operation, why? It is needed for the >> function to return the address of the _previous_ instruction. It >> matters when the call instruction is the last one in a function >> (because the callee is no-return), and return address is actually >> outside the function. >> >>>> #endif >>>> #if defined(__powerpc__) || defined(__powerpc64__) >>>> // PCs are always 4 byte aligned.
On Mon, May 06, 2013 at 08:52:21PM +0200, Christophe Lyon wrote: > --- a/gcc/config/arm/arm.c > +++ b/gcc/config/arm/arm.c > @@ -281,6 +281,8 @@ static unsigned arm_add_stmt_cost (void *data, int count, > > static void arm_canonicalize_comparison (int *code, rtx *op0, rtx *op1, > bool op0_preserve_value); > +static unsigned HOST_WIDE_INT arm_asan_shadow_offset (void); > + Unnecessary extra line? > --- a/gcc/testsuite/c-c++-common/asan/heap-overflow-1.c > +++ b/gcc/testsuite/c-c++-common/asan/heap-overflow-1.c > @@ -25,7 +25,7 @@ int main(int argc, char **argv) { > > /* { dg-output "READ of size 1 at 0x\[0-9a-f\]+ thread T0.*(\n|\r\n|\r)" } */ > /* { dg-output " #0 0x\[0-9a-f\]+ (in _*main > (\[^\n\r]*heap-overflow-1.c:21|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } */ > -/* { dg-output "0x\[0-9a-f\]+ is located 0 bytes to the right of > 10-byte region\[^\n\r]*(\n|\r\n|\r)" } */ > -/* { dg-output "allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */ > +/* { dg-output ".*0x\[0-9a-f\]+ is located 0 bytes to the right of > 10-byte region\[^\n\r]*(\n|\r\n|\r)" } */ > +/* { dg-output ".*allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */ Please avoid .* whenever possible, in dejagnu that includes newlines. So, use \[^\n\r]* instead unless it prints extra lines. Repeated many times through the patch. > --- a/libsanitizer/sanitizer_common/sanitizer_stacktrace.cc > +++ b/libsanitizer/sanitizer_common/sanitizer_stacktrace.cc > @@ -27,7 +27,7 @@ const char *StripPathPrefix(const char *filepath, > uptr StackTrace::GetPreviousInstructionPc(uptr pc) { > #ifdef __arm__ > // Cancel Thumb bit. > - pc = pc & (~1); > + return pc & (~1); > #endif > #if defined(__powerpc__) || defined(__powerpc64__) > // PCs are always 4 byte aligned. And this change needs to be merged from upstream libsanitizer. Jakub
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 0b97cf8..c036a21 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -281,6 +281,8 @@ static unsigned arm_add_stmt_cost (void *data, int count, static void arm_canonicalize_comparison (int *code, rtx *op0, rtx *op1, bool op0_preserve_value); +static unsigned HOST_WIDE_INT arm_asan_shadow_offset (void); + /* Table of machine attributes. */ static const struct attribute_spec arm_attribute_table[] = @@ -657,6 +659,9 @@ static const struct attribute_spec arm_attribute_table[] = #define TARGET_CANONICALIZE_COMPARISON \ arm_canonicalize_comparison +#undef TARGET_ASAN_SHADOW_OFFSET +#define TARGET_ASAN_SHADOW_OFFSET arm_asan_shadow_offset + struct gcc_target targetm = TARGET_INITIALIZER; /* Obstack for minipool constant handling. */ @@ -28062,4 +28067,12 @@ arm_validize_comparison (rtx *comparison, rtx * op1, rtx * op2) } +/* Implement the TARGET_ASAN_SHADOW_OFFSET hook. */ + +static unsigned HOST_WIDE_INT +arm_asan_shadow_offset (void) +{ + return (unsigned HOST_WIDE_INT) 1 << 29; +} + #include "gt-arm.h" diff --git a/gcc/config/arm/linux-eabi.h b/gcc/config/arm/linux-eabi.h index 23671a7..cb0aad1 100644 --- a/gcc/config/arm/linux-eabi.h +++ b/gcc/config/arm/linux-eabi.h @@ -84,10 +84,14 @@ LINUX_OR_ANDROID_LD (LINUX_TARGET_LINK_SPEC, \ LINUX_TARGET_LINK_SPEC " " ANDROID_LINK_SPEC) +#undef ASAN_CC1_SPEC +#define ASAN_CC1_SPEC "%{fsanitize=*:-funwind-tables}" + #undef CC1_SPEC #define CC1_SPEC \ - LINUX_OR_ANDROID_CC (GNU_USER_TARGET_CC1_SPEC, \ - GNU_USER_TARGET_CC1_SPEC " " ANDROID_CC1_SPEC) + LINUX_OR_ANDROID_CC (GNU_USER_TARGET_CC1_SPEC " " ASAN_CC1_SPEC, \ + GNU_USER_TARGET_CC1_SPEC " " ASAN_CC1_SPEC " " \ + ANDROID_CC1_SPEC) #define CC1PLUS_SPEC \ LINUX_OR_ANDROID_CC ("", ANDROID_CC1PLUS_SPEC) diff --git a/gcc/testsuite/c-c++-common/asan/clone-test-1.c b/gcc/testsuite/c-c++-common/asan/clone-test-1.c index d9acc0d..fd187aa 100644 --- a/gcc/testsuite/c-c++-common/asan/clone-test-1.c +++ b/gcc/testsuite/c-c++-common/asan/clone-test-1.c @@ -3,6 +3,7 @@ /* { dg-do run { target { *-*-linux* } } } */ /* { dg-require-effective-target clone } */ +/* { dg-require-effective-target hw } */ /* { dg-options "-D_GNU_SOURCE" } */ #include <stdio.h> diff --git a/gcc/testsuite/c-c++-common/asan/heap-overflow-1.c b/gcc/testsuite/c-c++-common/asan/heap-overflow-1.c index 43d47a3..e0b9038 100644 --- a/gcc/testsuite/c-c++-common/asan/heap-overflow-1.c +++ b/gcc/testsuite/c-c++-common/asan/heap-overflow-1.c @@ -25,7 +25,7 @@ int main(int argc, char **argv) { /* { dg-output "READ of size 1 at 0x\[0-9a-f\]+ thread T0.*(\n|\r\n|\r)" } */ /* { dg-output " #0 0x\[0-9a-f\]+ (in _*main (\[^\n\r]*heap-overflow-1.c:21|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } */ -/* { dg-output "0x\[0-9a-f\]+ is located 0 bytes to the right of 10-byte region\[^\n\r]*(\n|\r\n|\r)" } */ -/* { dg-output "allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output ".*0x\[0-9a-f\]+ is located 0 bytes to the right of 10-byte region\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output ".*allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */ /* { dg-output " #0 0x\[0-9a-f\]+ (in _*(interceptor_|)malloc|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ /* { dg-output " #1 0x\[0-9a-f\]+ (in _*main (\[^\n\r]*heap-overflow-1.c:19|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ diff --git a/gcc/testsuite/c-c++-common/asan/null-deref-1.c b/gcc/testsuite/c-c++-common/asan/null-deref-1.c index 2eee986..95e5036 100644 --- a/gcc/testsuite/c-c++-common/asan/null-deref-1.c +++ b/gcc/testsuite/c-c++-common/asan/null-deref-1.c @@ -18,6 +18,6 @@ int main() /* { dg-output "ERROR: AddressSanitizer:? SEGV on unknown address\[^\n\r]*" } */ /* { dg-output "0x\[0-9a-f\]+ \[^\n\r]*pc 0x\[0-9a-f\]+\[^\n\r]*(\n|\r\n|\r)" } */ -/* { dg-output "AddressSanitizer can not provide additional info.*(\n|\r\n|\r)" } */ +/* { dg-output ".*AddressSanitizer can not provide additional info.*(\n|\r\n|\r)" } */ /* { dg-output " #0 0x\[0-9a-f\]+ (in \[^\n\r]*NullDeref\[^\n\r]* (\[^\n\r]*null-deref-1.c:10|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ /* { dg-output " #1 0x\[0-9a-f\]+ (in _*main (\[^\n\r]*null-deref-1.c:15|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ diff --git a/gcc/testsuite/c-c++-common/asan/rlimit-mmap-test-1.c b/gcc/testsuite/c-c++-common/asan/rlimit-mmap-test-1.c index 0b3d2ae..9dbbc85 100644 --- a/gcc/testsuite/c-c++-common/asan/rlimit-mmap-test-1.c +++ b/gcc/testsuite/c-c++-common/asan/rlimit-mmap-test-1.c @@ -2,6 +2,7 @@ /* { dg-do run { target setrlimit } } */ /* { dg-skip-if "" { *-*-* } { "*" } { "-O0" } } */ +/* { dg-require-effective-target hw } */ /* { dg-shouldfail "asan" } */ #include <stdlib.h> diff --git a/gcc/testsuite/c-c++-common/asan/stack-overflow-1.c b/gcc/testsuite/c-c++-common/asan/stack-overflow-1.c index 790aa5e..5788b10 100644 --- a/gcc/testsuite/c-c++-common/asan/stack-overflow-1.c +++ b/gcc/testsuite/c-c++-common/asan/stack-overflow-1.c @@ -19,4 +19,4 @@ int main() { /* { dg-output "READ of size 1 at 0x\[0-9a-f\]+ thread T0\[^\n\r]*(\n|\r\n|\r)" } */ /* { dg-output " #0 0x\[0-9a-f\]+ (in _*main (\[^\n\r]*stack-overflow-1.c:16|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } */ -/* { dg-output "Address 0x\[0-9a-f\]+ is\[^\n\r]*frame <main>" } */ +/* { dg-output ".*Address 0x\[0-9a-f\]+ is\[^\n\r]*frame <main>" } */ diff --git a/gcc/testsuite/c-c++-common/asan/strncpy-overflow-1.c b/gcc/testsuite/c-c++-common/asan/strncpy-overflow-1.c index 10b3ad7..5e8ce40 100644 --- a/gcc/testsuite/c-c++-common/asan/strncpy-overflow-1.c +++ b/gcc/testsuite/c-c++-common/asan/strncpy-overflow-1.c @@ -15,7 +15,7 @@ int main(int argc, char **argv) { /* { dg-output "WRITE of size \[0-9\]* at 0x\[0-9a-f\]+ thread T0\[^\n\r]*(\n|\r\n|\r)" } */ /* { dg-output " #0 0x\[0-9a-f\]+ (in _*(interceptor_|)strncpy|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ /* { dg-output " #1 0x\[0-9a-f\]+ (in _*main (\[^\n\r]*strncpy-overflow-1.c:11|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } */ -/* { dg-output "0x\[0-9a-f\]+ is located 0 bytes to the right of 9-byte region\[^\n\r]*(\n|\r\n|\r)" } */ -/* { dg-output "allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output ".*0x\[0-9a-f\]+ is located 0 bytes to the right of 9-byte region\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output ".*allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */ /* { dg-output " #0 0x\[0-9a-f\]+ (in _*(interceptor_|)malloc|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ /* { dg-output " #1 0x\[0-9a-f\]+ (in _*main (\[^\n\r]*strncpy-overflow-1.c:10|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ diff --git a/gcc/testsuite/c-c++-common/asan/use-after-free-1.c b/gcc/testsuite/c-c++-common/asan/use-after-free-1.c index 939feeb..65318c8 100644 --- a/gcc/testsuite/c-c++-common/asan/use-after-free-1.c +++ b/gcc/testsuite/c-c++-common/asan/use-after-free-1.c @@ -11,12 +11,12 @@ int main() { /* { dg-output "ERROR: AddressSanitizer:? heap-use-after-free 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 "READ of size 1 at 0x\[0-9a-f\]+ thread T0\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output ".*READ of size 1 at 0x\[0-9a-f\]+ thread T0\[^\n\r]*(\n|\r\n|\r)" } */ /* { dg-output " #0 0x\[0-9a-f\]+ (in _*main (\[^\n\r]*use-after-free-1.c:9|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } */ -/* { dg-output "0x\[0-9a-f\]+ is located 5 bytes inside of 10-byte region .0x\[0-9a-f\]+,0x\[0-9a-f\]+\[^\n\r]*(\n|\r\n|\r)" } */ -/* { dg-output "freed by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output ".*0x\[0-9a-f\]+ is located 5 bytes inside of 10-byte region .0x\[0-9a-f\]+,0x\[0-9a-f\]+\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output ".*freed by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */ /* { dg-output " #0 0x\[0-9a-f\]+ (in _*(interceptor_|)free|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ /* { dg-output " #1 0x\[0-9a-f\]+ (in _*main (\[^\n\r]*use-after-free-1.c:8|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } */ -/* { dg-output "previously allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output ".*previously allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */ /* { dg-output " #0 0x\[0-9a-f\]+ (in _*(interceptor_|)malloc|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ /* { dg-output " #1 0x\[0-9a-f\]+ (in _*main (\[^\n\r]*use-after-free-1.c:7|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ diff --git a/gcc/testsuite/g++.dg/asan/deep-thread-stack-1.C b/gcc/testsuite/g++.dg/asan/deep-thread-stack-1.C index 12d8a7a..d29fe31 100644 --- a/gcc/testsuite/g++.dg/asan/deep-thread-stack-1.C +++ b/gcc/testsuite/g++.dg/asan/deep-thread-stack-1.C @@ -45,9 +45,9 @@ int main(int argc, char *argv[]) { } // { dg-output "ERROR: AddressSanitizer: heap-use-after-free.*(\n|\r\n|\r)" } -// { dg-output "WRITE of size 4 at 0x\[0-9a-f\]+ thread T(\[0-9\]+).*(\n|\r\n|\r)" } -// { dg-output "freed by thread T(\[0-9\]+) here:.*(\n|\r\n|\r)" } -// { dg-output "previously allocated by thread T(\[0-9\]+) here:.*(\n|\r\n|\r)" } +// { dg-output ".*WRITE of size 4 at 0x\[0-9a-f\]+ thread T(\[0-9\]+).*(\n|\r\n|\r)" } +// { dg-output ".*freed by thread T(\[0-9\]+) here:.*(\n|\r\n|\r)" } +// { dg-output ".*previously allocated by thread T(\[0-9\]+) here:.*(\n|\r\n|\r)" } // { dg-output "Thread T\\2 created by T(\[0-9\]+) here:.*(\n|\r\n|\r)" } // { dg-output "Thread T\\8 created by T0 here:.*(\n|\r\n|\r)" } // { dg-output "Thread T\\4 created by T(\[0-9\]+) here:.*(\n|\r\n|\r)" } diff --git a/gcc/testsuite/g++.dg/asan/large-func-test-1.C b/gcc/testsuite/g++.dg/asan/large-func-test-1.C index 32808e7..0d5c383 100644 --- a/gcc/testsuite/g++.dg/asan/large-func-test-1.C +++ b/gcc/testsuite/g++.dg/asan/large-func-test-1.C @@ -37,9 +37,9 @@ int main() { // { dg-output "ERROR: AddressSanitizer:? heap-buffer-overflow 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 "READ of size 4 at 0x\[0-9a-f\]+ thread T0\[^\n\r]*(\n|\r\n|\r)" } +// { dg-output ".*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 \[^\n\r]*LargeFunction\[^\n\r]*(large-func-test-1.C:18|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } -// { dg-output "0x\[0-9a-f\]+ is located 44 bytes to the right of 400-byte region.*(\n|\r\n|\r)" } -// { dg-output "allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } +// { dg-output ".*0x\[0-9a-f\]+ is located 44 bytes to the right of 400-byte region.*(\n|\r\n|\r)" } +// { dg-output ".*allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } // { dg-output " #0( 0x\[0-9a-f\]+ (in _*(interceptor_|)malloc|\[(\])\[^\n\r]*(\n|\r\n|\r)" } // { dg-output " #1|) 0x\[0-9a-f\]+ (in (operator new|_*_Zn\[aw\]\[mj\])|\[(\])\[^\n\r]*(\n|\r\n|\r)" } diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index 45c8b84..28b6b6d 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -4668,6 +4668,33 @@ proc check_effective_target_simulator { } { return 0 } +# Return 1 if programs are intended to be run on hardware rather than +# on a simulator + +proc check_effective_target_hw { } { + + # All "src/sim" simulators set this one. + if [board_info target exists is_simulator] { + if [board_info target is_simulator] { + return 0 + } else { + return 1 + } + } + + # The "sid" simulators don't set that one, but at least they set + # this one. + if [board_info target exists slow_simulator] { + if [board_info target slow_simulator] { + return 0 + } else { + return 1 + } + } + + return 1 +} + # Return 1 if the target is a VxWorks kernel. proc check_effective_target_vxworks_kernel { } { diff --git a/libsanitizer/configure.tgt b/libsanitizer/configure.tgt index 265da01..bdfc22e 100644 --- a/libsanitizer/configure.tgt +++ b/libsanitizer/configure.tgt @@ -29,6 +29,8 @@ case "${target}" in ;; sparc*-*-linux*) ;; + arm*-*-linux*) + ;; x86_64-*-darwin[1]* | i?86-*-darwin[1]*) TSAN_SUPPORTED=no ;; diff --git a/libsanitizer/sanitizer_common/sanitizer_stacktrace.cc b/libsanitizer/sanitizer_common/sanitizer_stacktrace.cc index e14ea44..7b3e4ca 100644 --- a/libsanitizer/sanitizer_common/sanitizer_stacktrace.cc +++ b/libsanitizer/sanitizer_common/sanitizer_stacktrace.cc @@ -27,7 +27,7 @@ const char *StripPathPrefix(const char *filepath, uptr StackTrace::GetPreviousInstructionPc(uptr pc) { #ifdef __arm__ // Cancel Thumb bit. - pc = pc & (~1); + return pc & (~1); #endif #if defined(__powerpc__) || defined(__powerpc64__) // PCs are always 4 byte aligned.