Re: [PATCH][PR sanitizer/84250] Avoid global symbols collision when using both ASan and UBSan

2018-07-04 Thread Maxim Ostapenko
Hi Jeff,

On 07/04/2018 05:45 AM, Jeff Law wrote:
> On 05/23/2018 11:15 AM, Maxim Ostapenko wrote:
>> Hi,
>>
>>
>> as described in PR, when using both ASan and UBSan
>> (-fsanitize=address,undefined ), we have symbols collision for global
>> functions, like __sanitizer_set_report_path. This leads to fuzzy results
>> when printing reports into files e.g. for this test case:
>>
>> #include 
>> int main(int argc, char **argv) {
>>     __sanitizer_set_report_path("/tmp/sanitizer.txt");
>>     int i = 23;
>>     i <<= 32;
>>     int *array = new int[100];
>>     delete [] array;
>>     return array[argc];
>> }
>>
>> only ASan's report gets written to file; UBSan output goes to stderr.
>>
>> To resolve this issue we could use two approaches:
>>
>> 1) Use the same approach to that is implemented in Clang (UBSan embedded
>> to ASan). The only caveat here is that we need to link (unused) C++ part
>> of UBSan even in C programs when linking static ASan runtime. This
>> happens because GCC, as opposed to Clang, doesn't split C and C++
>> runtimes for sanitizers.
>>
>> 2) Just add SANITIZER_INTERFACE_ATTRIBUTE to report_file global
>> variable. In this case all __sanitizer_set_report_path calls will set
>> the same report_file variable. IMHO this is a hacky way to fix the
>> issue, it's better to use the first option if possible.
>>
>>
>> The attached patch fixes the symbols collision by embedding UBSan into
>> ASan (variant 1), just like we do for LSan.
>>
>>
>> Regtested/bootstrapped on x86_64-unknown-linux-gnu, looks reasonable
>> enough for trunk?
>>
>>
>> -Maxim
>>
>>
>> pr84250-2.diff
>>
>>
>> gcc/ChangeLog:
>>
>> 2018-05-23  Maxim Ostapenko  
>>
>>  * config/gnu-user.h (LIBASAN_EARLY_SPEC): Pass -lstdc++ for static
>>  libasan.
>>  * gcc.c: Do not pass LIBUBSAN_SPEC if ASan is enabled with UBSan.
>>
>> libsanitizer/ChangeLog:
>>
>> 2018-05-23  Maxim Ostapenko  
>>
>>  * Makefile.am: Reorder libs.
>>  * Makefile.in: Regenerate.
>>  * asan/Makefile.am: Define DCAN_SANITIZE_UB=1, add dependancy from
>>  libsanitizer_ubsan.la.
>>  * asan/Makefile.in: Regenerate.
>>  * ubsan/Makefile.am: Define new libsanitizer_ubsan.la library.
>>  * ubsan/Makefile.in: Regenerate.
> You know this code better than anyone else working on GCC.  My only
> concern would be the kernel builds with asan, but I suspect they're
> providing their own runtime anyway, so the libstdc++ caveat shouldn't apply.

Yes, you are right, kernel provides its own runtime.

>
> OK for the trunk.

Ok, thanks, I'll apply the patch today (with fixed ChangeLog entry).

-Maxim

> jeff
>
>
>



Re: [PATCH][PR sanitizer/84250] Avoid global symbols collision when using both ASan and UBSan

2018-07-05 Thread Maxim Ostapenko
On 07/05/2018 12:01 PM, Jakub Jelinek wrote:
> On Wed, Jul 04, 2018 at 08:20:47PM +0300, Maxim Ostapenko wrote:
>> On 07/04/2018 05:45 AM, Jeff Law wrote:
>>> On 05/23/2018 11:15 AM, Maxim Ostapenko wrote:
>>>> as described in PR, when using both ASan and UBSan
>>>> (-fsanitize=address,undefined ), we have symbols collision for global
>>>> functions, like __sanitizer_set_report_path. This leads to fuzzy results
>>>> when printing reports into files e.g. for this test case:
>>>>
>>>> #include 
>>>> int main(int argc, char **argv) {
>>>>  __sanitizer_set_report_path("/tmp/sanitizer.txt");
>>>>  int i = 23;
>>>>  i <<= 32;
>>>>  int *array = new int[100];
>>>>  delete [] array;
>>>>  return array[argc];
>>>> }
>>>>
>>>> only ASan's report gets written to file; UBSan output goes to stderr.
>>>>
>>>> To resolve this issue we could use two approaches:
>>>>
>>>> 1) Use the same approach to that is implemented in Clang (UBSan embedded
>>>> to ASan). The only caveat here is that we need to link (unused) C++ part
>>>> of UBSan even in C programs when linking static ASan runtime. This
>>>> happens because GCC, as opposed to Clang, doesn't split C and C++
>>>> runtimes for sanitizers.
>>>>
>>>> 2) Just add SANITIZER_INTERFACE_ATTRIBUTE to report_file global
>>>> variable. In this case all __sanitizer_set_report_path calls will set
>>>> the same report_file variable. IMHO this is a hacky way to fix the
>>>> issue, it's better to use the first option if possible.
>>>>
>>>>
>>>> The attached patch fixes the symbols collision by embedding UBSan into
>>>> ASan (variant 1), just like we do for LSan.
>>>>
>>>>
>>>> Regtested/bootstrapped on x86_64-unknown-linux-gnu, looks reasonable
>>>> enough for trunk?
>>>>
>>>>
>>>> -Maxim
>>>>
>>>>
>>>> pr84250-2.diff
>>>>
>>>>
>>>> gcc/ChangeLog:
>>>>
>>>> 2018-05-23  Maxim Ostapenko  
>>>>
>>>>* config/gnu-user.h (LIBASAN_EARLY_SPEC): Pass -lstdc++ for static
>>>>libasan.
>>>>* gcc.c: Do not pass LIBUBSAN_SPEC if ASan is enabled with UBSan.
>>>>
>>>> libsanitizer/ChangeLog:
>>>>
>>>> 2018-05-23  Maxim Ostapenko  
>>>>
>>>>* Makefile.am: Reorder libs.
>>>>* Makefile.in: Regenerate.
>>>>* asan/Makefile.am: Define DCAN_SANITIZE_UB=1, add dependancy from
>>>>libsanitizer_ubsan.la.
>>>>* asan/Makefile.in: Regenerate.
>>>>* ubsan/Makefile.am: Define new libsanitizer_ubsan.la library.
>>>>* ubsan/Makefile.in: Regenerate.
>>> You know this code better than anyone else working on GCC.  My only
>>> concern would be the kernel builds with asan, but I suspect they're
>>> providing their own runtime anyway, so the libstdc++ caveat shouldn't apply.
>> Yes, you are right, kernel provides its own runtime.
>>
>>> OK for the trunk.
>> Ok, thanks, I'll apply the patch today (with fixed ChangeLog entry).
> This broke the c-c++-common/asan/pr59063-2.c test:
>
> FAIL: c-c++-common/asan/pr59063-2.c   -O1  (test for excess errors)
> Excess errors:
> /usr/bin/ld: cannot find -lstdc++

I must mis-looked this, sorry :(.

> While it could be fixed by tweaking asan-dg.exp, thinking about this, the
> 1) variant is actually not a good idea, it will not work properly anyway
> if you link one library with -fsanitize=undefined and another library
> with -fsanitize=address, the right solution is to make the two libraries
> coexist sanely

Yes, you're right. Btw, we have pretty the same situation with ASan + 
LSan, right?

> , so I'd prefer 2) or if not exporting a variable, export
> an accessor function to get the address of the variable (or whole block of
> shared state in one object between the libraries).
>
> Yes, it means trying to get something accepted upstream, but anything else
> is an ugly hack.

Ok. Could you please revert this patch for me (I don't have a write 
access to repo right now) so we can cook a proper fix?

-Maxim

>
>   Jakub
>
>
>



[PATCH, Libbacktrace] Fix possible SEGV when handling stripped PIE binaries.

2016-03-02 Thread Maxim Ostapenko

Hi!

When testing ASan on large system, I've noticed that sometimes it 
crashes with SEGV in Libbacktrace when trying to symbolize stripped PIE 
(compiled with -pie -fPIC) binaries in fully stripped environment (this 
means that all dependent libraries are also stripped). Here a scenario 
I've observed:


1) _asan_backtrace_initialize calls elf_add passing &elf_fileline_fn as 
output parameter to properly initialize it.
2) elf_add doesn't elf_fileline_fn initialize and returns -1 for 
stripped PIE binary.
3) _asan_backtrace_initialize calls phdr_callback on each dependent 
library via dl_iterate_phdr.
4) phdr_callback initializes elf_fileline_fn iff it found debug info in 
some library (found_dwarf == 1), but this is false since all libs are 
stripped. So, we still have uninitialized elf_fileline_fn value.
5) _asan_backtrace_initialize uses elf_fileline_fn to initialize proper 
fileline_fn callback.
6) Libbacktrace uses fileline_fn callback later and crashes because it 
contains garbage.


This patch fixes the issue by simply initializing elf_fileline_fn via 
elf_nodebug in _asan_backtrace_initialize prologue.


Tested on x86_64-linux-gnu and arm-linux-gnueabi, OK for trunk?

-Maxim
libbacktrace/ChangeLog:

2016-03-02  Maxim Ostapenko  

	* elf.c (backtrace_initialize): Properly initialize elf_fileline_fn to
	avoid possible crash.

diff --git a/libbacktrace/elf.c b/libbacktrace/elf.c
index 05cc5c0..c7168c6 100644
--- a/libbacktrace/elf.c
+++ b/libbacktrace/elf.c
@@ -925,7 +925,7 @@ backtrace_initialize (struct backtrace_state *state, int descriptor,
   int ret;
   int found_sym;
   int found_dwarf;
-  fileline elf_fileline_fn;
+  fileline elf_fileline_fn = elf_nodebug;
   struct phdr_data pd;
 
   ret = elf_add (state, descriptor, 0, error_callback, data, &elf_fileline_fn,


Re: [PATCH, Libbacktrace] Fix possible SEGV when handling stripped PIE binaries.

2016-03-02 Thread Maxim Ostapenko

On 02/03/16 16:59, Ian Lance Taylor wrote:

On Wed, Mar 2, 2016 at 12:51 AM, Maxim Ostapenko
 wrote:

When testing ASan on large system, I've noticed that sometimes it crashes
with SEGV in Libbacktrace when trying to symbolize stripped PIE (compiled
with -pie -fPIC) binaries in fully stripped environment (this means that all
dependent libraries are also stripped). Here a scenario I've observed:

1) _asan_backtrace_initialize calls elf_add passing &elf_fileline_fn as
output parameter to properly initialize it.
2) elf_add doesn't elf_fileline_fn initialize and returns -1 for stripped
PIE binary.
3) _asan_backtrace_initialize calls phdr_callback on each dependent library
via dl_iterate_phdr.
4) phdr_callback initializes elf_fileline_fn iff it found debug info in some
library (found_dwarf == 1), but this is false since all libs are stripped.
So, we still have uninitialized elf_fileline_fn value.
5) _asan_backtrace_initialize uses elf_fileline_fn to initialize proper
fileline_fn callback.
6) Libbacktrace uses fileline_fn callback later and crashes because it
contains garbage.

This patch fixes the issue by simply initializing elf_fileline_fn via
elf_nodebug in _asan_backtrace_initialize prologue.

Tested on x86_64-linux-gnu and arm-linux-gnueabi, OK for trunk?

Thanks for the analysis.  I would rather set *fileline_fn in the case
where elf_add returns -1.  Or, remove the setting of *fileline_fn =
elf_nodebug in elf_add, since that would become the default.

Ian



Thanks, does this look better (I used the second option)?

-Maxim
libbacktrace/ChangeLog:

2016-03-02  Maxim Ostapenko  

	* elf.c (backtrace_initialize): Properly initialize elf_fileline_fn to
	avoid possible crash.
	(elf_add): Don't set *fileline_fn to elf_nodebug value in case of
	missing debug info anymore.

diff --git a/libbacktrace/elf.c b/libbacktrace/elf.c
index 05cc5c0..f85ac65 100644
--- a/libbacktrace/elf.c
+++ b/libbacktrace/elf.c
@@ -791,7 +791,6 @@ elf_add (struct backtrace_state *state, int descriptor, uintptr_t base_address,
 {
   if (!backtrace_close (descriptor, error_callback, data))
 	goto fail;
-  *fileline_fn = elf_nodebug;
   return 1;
 }
 
@@ -925,7 +924,7 @@ backtrace_initialize (struct backtrace_state *state, int descriptor,
   int ret;
   int found_sym;
   int found_dwarf;
-  fileline elf_fileline_fn;
+  fileline elf_fileline_fn = elf_nodebug;
   struct phdr_data pd;
 
   ret = elf_add (state, descriptor, 0, error_callback, data, &elf_fileline_fn,


Re: RFC ThreadSanitizer tests

2013-12-05 Thread Maxim Ostapenko

> Instead of mentioning the directory in the ChangeLog,
> mention the individual test files.
> ...
>* g++.dg/dg.exp: Prune tsan subdirectory.

Thanks, I fixed the ChangeLog file.

> how long does it take to run make check-gcc check-g++ 
RUNTESTFLAGS=tsan.exp ?

> How much memory does it need?

I've run `make check-gcc RUNTESTFLAGS=tsan.exp' (this also includes c++ 
tests) under `/usr/bin/time -v' and got:


-Elapsed (wall clock) time (h:mm:ss or m:ss): 3:17.04
-Maximum resident set size (kbytes): 199872 kbytes

The same numbers for asan are (/usr/bin/time -v make check-gcc 
RUNTESTFLAGS=asan.exp):

-Elapsed (wall clock) time (h:mm:ss or m:ss): 3:56.38
-Maximum resident set size (kbytes): 3155264 kbytes

-Maxim
2013-12-05  Max Ostapenko < m.ostape...@partner.samsung.com >

* c-c++-common/tsan/atomic_stack.c: New test.
* c-c++-common/tsan/fd_pipe_race.c: New test.
* c-c++-common/tsan/free_race.c: New test.
* c-c++-common/tsan/mutexset1.c: New test.
* c-c++-common/tsan/race_on_barrier.c: New test.
* c-c++-common/tsan/sleep_sync.c: New test.
* c-c++-common/tsan/thread_leak.c: New test.
* c-c++-common/tsan/thread_leak1.c: New test.
* c-c++-common/tsan/thread_leak2.c: New test.
* c-c++-common/tsan/tiny_race.c: New test.
* c-c++-common/tsan/tls_race.c: New test.
* c-c++-common/tsan/write_in_reader_lock.c: New test.   
* lib/tsan-dg.exp: New file.
* gcc.dg/tsan/tsan.exp: New file.
* g++.dg/tsan/tsan.exp: New file.
* g++.dg/dg.exp: Prune tsan subdirectory.
diff --git a/gcc/testsuite/c-c++-common/tsan/atomic_stack.c b/gcc/testsuite/c-c++-common/tsan/atomic_stack.c
new file mode 100644
index 000..eac71b8
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/tsan/atomic_stack.c
@@ -0,0 +1,32 @@
+/* { dg-do run } */
+/* { dg-shouldfail "tsan" } */
+
+#include 
+#include 
+
+int Global;
+
+void *Thread1(void *x) {
+  sleep(1);
+  __atomic_fetch_add(&Global, 1, __ATOMIC_RELAXED);
+  return NULL;
+}
+
+void *Thread2(void *x) {
+  Global++;
+  return NULL;
+}
+
+int main() {
+  pthread_t t[2];
+  pthread_create(&t[0], NULL, Thread1, NULL);
+  pthread_create(&t[1], NULL, Thread2, NULL);
+  pthread_join(t[0], NULL);
+  pthread_join(t[1], NULL);
+  return 0;
+}
+
+/* { dg-output "WARNING: ThreadSanitizer: data race.*(\n|\r\n|\r)" } */
+/* { dg-output "  Atomic write of size 4.*" } */
+/* { dg-output "#0 __tsan_atomic32_fetch_add.*" } */
+/* { dg-output "#1 Thread1.*" } */
diff --git a/gcc/testsuite/c-c++-common/tsan/fd_pipe_race.c b/gcc/testsuite/c-c++-common/tsan/fd_pipe_race.c
new file mode 100644
index 000..fc76cbf
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/tsan/fd_pipe_race.c
@@ -0,0 +1,37 @@
+/* { dg-do run } */
+/* { dg-shouldfail "tsan" } */
+
+#include 
+#include 
+#include 
+
+int fds[2];
+
+void *Thread1(void *x) {
+  write(fds[1], "a", 1);
+  return NULL;
+}
+
+void *Thread2(void *x) {
+  sleep(1);
+  close(fds[0]);
+  close(fds[1]);
+  return NULL;
+}
+
+int main() {
+  pipe(fds);
+  pthread_t t[2];
+  pthread_create(&t[0], NULL, Thread1, NULL);
+  pthread_create(&t[1], NULL, Thread2, NULL);
+  pthread_join(t[0], NULL);
+  pthread_join(t[1], NULL);
+}
+
+/* { dg-output "WARNING: ThreadSanitizer: data race.*\n" } */
+/* { dg-output "  Write of size 8.*\n" } */
+/* { dg-output "#0 close.*\n" } */
+/* { dg-output "#1 Thread2.*\n" } */
+/* { dg-output "  Previous read of size 8.*\n" } */
+/* { dg-output "#0 write.*\n" } */
+/* { dg-output "#1 Thread1.*\n" } */
diff --git a/gcc/testsuite/c-c++-common/tsan/free_race.c b/gcc/testsuite/c-c++-common/tsan/free_race.c
new file mode 100644
index 000..362c92b
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/tsan/free_race.c
@@ -0,0 +1,28 @@
+/* { dg-do run } */
+/* { dg-shouldfail "tsan" } */
+
+#include 
+
+void __attribute__((noinline)) foo(int *mem) {
+  free(mem);
+}
+
+void __attribute__((noinline)) bar(int *mem) {
+  mem[0] = 42;
+}
+
+int main() {
+  int *mem =(int*)malloc (100);
+  foo(mem);
+  bar(mem);
+  return 0;
+}
+
+/* { dg-output "WARNING: ThreadSanitizer: heap-use-after-free.*(\n|\r\n|\r)" } */
+/* { dg-output "  Write of size 4 at.* by main thread:(\n|\r\n|\r)" } */
+/* { dg-output "#0 bar.*(\n|\r\n|\r)" } */
+/* { dg-output "#1 main.*(\n|\r\n|\r)" } */
+/* { dg-output "  Previous write of size 8 at.* by main thread:(\n|\r\n|\r)" } */
+/* { dg-output "#0 free.*(\n|\r\n|\r)" } */
+/* { dg-output "#\(1|2\) foo.*(\n|\r\n|\r)" } */
+/* { dg-output "#\(2|3\) main.*(\n|\r\n|\r)" } */
diff --git a/gcc/testsuite/c-c++-common/tsan/mutexset1.c b/gcc/testsuite/c-c++-common/tsan/mutexset1.c
new file mode 100644
index 000..783f262
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/tsan/mutexset1.c
@@ -0,0 +1,41 @@
+/* { dg-do run } */
+/* { dg-shouldfail "tsan" } */
+
+#include 
+#include 
+#include 
+
+int Global;
+pthread_mutex_t mtx;
+
+void *Thread1(void *x) {
+  sleep(1);
+  pthread_mut

Re: RFC ThreadSanitizer tests

2013-12-05 Thread Maxim Ostapenko

> 2013-12-05  Max Ostapenko < m.ostape...@partner.samsung.com >
> 2013-12-05  Max Ostapenko  actually.

Ok, I'm sorry, I'll fix it. Ok to commit?

-Maxim
2013-12-05  Max Ostapenko  

* c-c++-common/tsan/atomic_stack.c: New test.
* c-c++-common/tsan/fd_pipe_race.c: New test.
* c-c++-common/tsan/free_race.c: New test.
* c-c++-common/tsan/mutexset1.c: New test.
* c-c++-common/tsan/race_on_barrier.c: New test.
* c-c++-common/tsan/sleep_sync.c: New test.
* c-c++-common/tsan/thread_leak.c: New test.
* c-c++-common/tsan/thread_leak1.c: New test.
* c-c++-common/tsan/thread_leak2.c: New test.
* c-c++-common/tsan/tiny_race.c: New test.
* c-c++-common/tsan/tls_race.c: New test.
* c-c++-common/tsan/write_in_reader_lock.c: New test.   
* lib/tsan-dg.exp: New file.
* gcc.dg/tsan/tsan.exp: New file.
* g++.dg/tsan/tsan.exp: New file.
* g++.dg/dg.exp: Prune tsan subdirectory.
diff --git a/gcc/testsuite/c-c++-common/tsan/atomic_stack.c b/gcc/testsuite/c-c++-common/tsan/atomic_stack.c
new file mode 100644
index 000..eac71b8
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/tsan/atomic_stack.c
@@ -0,0 +1,32 @@
+/* { dg-do run } */
+/* { dg-shouldfail "tsan" } */
+
+#include 
+#include 
+
+int Global;
+
+void *Thread1(void *x) {
+  sleep(1);
+  __atomic_fetch_add(&Global, 1, __ATOMIC_RELAXED);
+  return NULL;
+}
+
+void *Thread2(void *x) {
+  Global++;
+  return NULL;
+}
+
+int main() {
+  pthread_t t[2];
+  pthread_create(&t[0], NULL, Thread1, NULL);
+  pthread_create(&t[1], NULL, Thread2, NULL);
+  pthread_join(t[0], NULL);
+  pthread_join(t[1], NULL);
+  return 0;
+}
+
+/* { dg-output "WARNING: ThreadSanitizer: data race.*(\n|\r\n|\r)" } */
+/* { dg-output "  Atomic write of size 4.*" } */
+/* { dg-output "#0 __tsan_atomic32_fetch_add.*" } */
+/* { dg-output "#1 Thread1.*" } */
diff --git a/gcc/testsuite/c-c++-common/tsan/fd_pipe_race.c b/gcc/testsuite/c-c++-common/tsan/fd_pipe_race.c
new file mode 100644
index 000..fc76cbf
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/tsan/fd_pipe_race.c
@@ -0,0 +1,37 @@
+/* { dg-do run } */
+/* { dg-shouldfail "tsan" } */
+
+#include 
+#include 
+#include 
+
+int fds[2];
+
+void *Thread1(void *x) {
+  write(fds[1], "a", 1);
+  return NULL;
+}
+
+void *Thread2(void *x) {
+  sleep(1);
+  close(fds[0]);
+  close(fds[1]);
+  return NULL;
+}
+
+int main() {
+  pipe(fds);
+  pthread_t t[2];
+  pthread_create(&t[0], NULL, Thread1, NULL);
+  pthread_create(&t[1], NULL, Thread2, NULL);
+  pthread_join(t[0], NULL);
+  pthread_join(t[1], NULL);
+}
+
+/* { dg-output "WARNING: ThreadSanitizer: data race.*\n" } */
+/* { dg-output "  Write of size 8.*\n" } */
+/* { dg-output "#0 close.*\n" } */
+/* { dg-output "#1 Thread2.*\n" } */
+/* { dg-output "  Previous read of size 8.*\n" } */
+/* { dg-output "#0 write.*\n" } */
+/* { dg-output "#1 Thread1.*\n" } */
diff --git a/gcc/testsuite/c-c++-common/tsan/free_race.c b/gcc/testsuite/c-c++-common/tsan/free_race.c
new file mode 100644
index 000..362c92b
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/tsan/free_race.c
@@ -0,0 +1,28 @@
+/* { dg-do run } */
+/* { dg-shouldfail "tsan" } */
+
+#include 
+
+void __attribute__((noinline)) foo(int *mem) {
+  free(mem);
+}
+
+void __attribute__((noinline)) bar(int *mem) {
+  mem[0] = 42;
+}
+
+int main() {
+  int *mem =(int*)malloc (100);
+  foo(mem);
+  bar(mem);
+  return 0;
+}
+
+/* { dg-output "WARNING: ThreadSanitizer: heap-use-after-free.*(\n|\r\n|\r)" } */
+/* { dg-output "  Write of size 4 at.* by main thread:(\n|\r\n|\r)" } */
+/* { dg-output "#0 bar.*(\n|\r\n|\r)" } */
+/* { dg-output "#1 main.*(\n|\r\n|\r)" } */
+/* { dg-output "  Previous write of size 8 at.* by main thread:(\n|\r\n|\r)" } */
+/* { dg-output "#0 free.*(\n|\r\n|\r)" } */
+/* { dg-output "#\(1|2\) foo.*(\n|\r\n|\r)" } */
+/* { dg-output "#\(2|3\) main.*(\n|\r\n|\r)" } */
diff --git a/gcc/testsuite/c-c++-common/tsan/mutexset1.c b/gcc/testsuite/c-c++-common/tsan/mutexset1.c
new file mode 100644
index 000..783f262
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/tsan/mutexset1.c
@@ -0,0 +1,41 @@
+/* { dg-do run } */
+/* { dg-shouldfail "tsan" } */
+
+#include 
+#include 
+#include 
+
+int Global;
+pthread_mutex_t mtx;
+
+void *Thread1(void *x) {
+  sleep(1);
+  pthread_mutex_lock(&mtx);
+  Global++;
+  pthread_mutex_unlock(&mtx);
+  return NULL;
+}
+
+void *Thread2(void *x) {
+  Global--;
+  return NULL;/* { dg-output ".*" } */
+
+}
+
+int main() {
+  pthread_mutex_init(&mtx, 0);
+  pthread_t t[2];
+  pthread_create(&t[0], NULL, Thread1, NULL);
+  pthread_create(&t[1], NULL, Thread2, NULL);
+  pthread_join(t[0], NULL);
+  pthread_join(t[1], NULL);
+  pthread_mutex_destroy(&mtx);
+  return 0;
+}
+
+/* { dg-output "WARNING: ThreadSanitizer: data race.*(\n|\r\n|\r)" } */
+/* { dg-output "  Read of size 4 at 0x\[0-9a-f\]+ by thread T1 \\(mutexes: write M\[0-9\]\\):.*" 

Fix tsan tests.

2013-12-10 Thread Maxim Ostapenko

Hello,

From http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59410#c1 issue:

> BTW, the tsan.exp tests don't seem to be as cheap as was claimed 
during the patch
> submission, I'd prefer to at least throttle the > torture options 
down to say -O0
> and -O2 rather than so many different variants when the tests are 
really small and

> optimizations don't really affect them that much if at all.

I've fixed tsan tests to be executed only with '-O0' and '-O2' options.
The number of tests executed is decreased from 272 to 68.
Ok to commit?

-Maxim
diff --git a/gcc/testsuite/c-c++-common/tsan/thread_leak2.c b/gcc/testsuite/c-c++-common/tsan/thread_leak2.c
index 12ac734..d6f4e22 100644
--- a/gcc/testsuite/c-c++-common/tsan/thread_leak2.c
+++ b/gcc/testsuite/c-c++-common/tsan/thread_leak2.c
@@ -1,6 +1,5 @@
 /* { dg-do run } */
 /* { dg-shouldfail "tsan" } */
-/* { dg-skip-if "" { *-*-* }  { "-O3 -funroll-loops" "-O3 -funroll-all-loops" } { "" } } */
 
 #include 
 #include 
diff --git a/gcc/testsuite/g++.dg/tsan/tsan.exp b/gcc/testsuite/g++.dg/tsan/tsan.exp
index 164a92e..68b1d83 100644
--- a/gcc/testsuite/g++.dg/tsan/tsan.exp
+++ b/gcc/testsuite/g++.dg/tsan/tsan.exp
@@ -21,6 +21,7 @@
 # Load support procs.
 load_lib g++-dg.exp
 load_lib tsan-dg.exp
+load_lib torture-options.exp
 
 if ![check_effective_target_fthread_sanitizer] {
   return
@@ -28,6 +29,11 @@ if ![check_effective_target_fthread_sanitizer] {
 
 # Initialize `dg'.
 dg-init
+torture-init
+set-torture-options [list \
+	{ -O0 } \
+	{ -O2 } ]
+
 if [tsan_init] {
 
 # Main loop.
diff --git a/gcc/testsuite/gcc.dg/tsan/tsan.exp b/gcc/testsuite/gcc.dg/tsan/tsan.exp
index 248cfb1..a4a5b72 100644
--- a/gcc/testsuite/gcc.dg/tsan/tsan.exp
+++ b/gcc/testsuite/gcc.dg/tsan/tsan.exp
@@ -21,6 +21,7 @@
 # Load support procs.
 load_lib gcc-dg.exp
 load_lib tsan-dg.exp
+load_lib torture-options.exp
 
 if ![check_effective_target_fthread_sanitizer] {
   return
@@ -28,6 +29,11 @@ if ![check_effective_target_fthread_sanitizer] {
 
 # Initialize `dg'.
 dg-init
+torture-init
+set-torture-options [list \
+	{ -O0 } \
+	{ -O2 } ]
+
 if [tsan_init] {
 
 # Main loop.
2013-12-10  Max Ostapenko  

* c-c++-common/tsan/thread_leak2.c: `dg-skip-if' removed.
* gcc-dg/tsan/tsan.exp: Run only with '-O0' and '-O2' options.
* g++-dg/tsan/tsan.exp: Run only with '-O0' and '-O2' options.


New tsan tests.

2013-12-11 Thread Maxim Ostapenko

Hi all,

I've added new  tests for tsan from LLVM.

Tested on x86_64.

Ok to commit?

-Maxim
diff --git a/gcc/testsuite/c-c++-common/tsan/free_race2.c b/gcc/testsuite/c-c++-common/tsan/free_race2.c
new file mode 100644
index 000..3c15d2d
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/tsan/free_race2.c
@@ -0,0 +1,29 @@
+/* { dg-do run } */
+/* { dg-shouldfail "tsan" } */
+
+#include 
+
+void __attribute__((noinline)) foo(int *mem) {
+  free(mem);
+}
+
+void __attribute__((noinline)) bar(int *mem) {
+  mem[0] = 42;
+}
+
+int main() {
+  int *mem = (int*)malloc(100);
+  foo(mem);
+  bar(mem);
+  return 0;
+}
+
+/* { dg-output "WARNING: ThreadSanitizer: heap-use-after-free.*(\n|\r\n|\r)" } */
+/* { dg-output "  Write of size 4.* by main thread:(\n|\r\n|\r)" } */
+/* { dg-output "#0 bar.*" } */
+/* { dg-output "#1 main .*" } */
+/* { dg-output "  Previous write of size 8 at .* by main thread:(\n|\r\n|\r)" } */
+/* { dg-output "#0 free .*" } */
+/* { dg-output "#\(1|2\) foo.*(\n|\r\n|\r)" } */
+/* { dg-output "#\(2|3\) main .*" } */
+
diff --git a/gcc/testsuite/c-c++-common/tsan/race_on_barrier2.c b/gcc/testsuite/c-c++-common/tsan/race_on_barrier2.c
new file mode 100644
index 000..9576c67
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/tsan/race_on_barrier2.c
@@ -0,0 +1,33 @@
+/* { dg-do run } */
+/* { dg-shouldfail "tsan" } */
+
+#include 
+#include 
+#include 
+#include 
+
+pthread_barrier_t B;
+int Global;
+
+void *Thread1(void *x) {
+  if (pthread_barrier_wait(&B) == PTHREAD_BARRIER_SERIAL_THREAD)
+pthread_barrier_destroy(&B);
+  return NULL;
+}
+
+void *Thread2(void *x) {
+  if (pthread_barrier_wait(&B) == PTHREAD_BARRIER_SERIAL_THREAD)
+pthread_barrier_destroy(&B);
+  return NULL;
+}
+
+int main() {
+  pthread_barrier_init(&B, 0, 2);
+  pthread_t t;
+  pthread_create(&t, NULL, Thread1, NULL);
+  Thread2(0);
+  pthread_join(t, NULL);
+  return 0;
+}
+
+/* { dg-output "WARNING: ThreadSanitizer: data race.*(\n|\r\n|\r)" } */
diff --git a/gcc/testsuite/c-c++-common/tsan/race_on_mutex.c b/gcc/testsuite/c-c++-common/tsan/race_on_mutex.c
new file mode 100644
index 000..f112d09
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/tsan/race_on_mutex.c
@@ -0,0 +1,44 @@
+/* { dg-do run } */
+/* { dg-shouldfail "tsan" } */
+
+#include 
+#include 
+#include 
+#include 
+
+pthread_mutex_t Mtx;
+int Global;
+
+void *Thread1(void *x) {
+  pthread_mutex_init(&Mtx, 0);
+  pthread_mutex_lock(&Mtx);
+  Global = 42;
+  pthread_mutex_unlock(&Mtx);
+  return NULL;
+}
+
+void *Thread2(void *x) {
+  sleep(1);
+  pthread_mutex_lock(&Mtx);
+  Global = 43;
+  pthread_mutex_unlock(&Mtx);
+  return NULL;
+}
+
+int main() {
+  pthread_t t[2];
+  pthread_create(&t[0], NULL, Thread1, NULL);
+  pthread_create(&t[1], NULL, Thread2, NULL);
+  pthread_join(t[0], NULL);
+  pthread_join(t[1], NULL);
+  pthread_mutex_destroy(&Mtx);
+  return 0;
+}
+
+/* { dg-output "WARNING: ThreadSanitizer: data race.*(\n|\r\n|\r)" } */
+/* { dg-output "  Atomic read of size 1 at .* by thread T2:(\n|\r\n|\r)" } */
+/* { dg-output "#0 pthread_mutex_lock.*" } */
+/* { dg-output "#1 Thread2.* .*(race_on_mutex.c:22|\\?{2}:0) (.*)" } */
+/* { dg-output "  Previous write of size 1 at .* by thread T1:(\n|\r\n|\r)" } */
+/* { dg-output "#0 pthread_mutex_init .* (.)*" } */
+/* { dg-output "#1 Thread1.* .*(race_on_mutex.c:13|\\?{2}:0) .*" } */
diff --git a/gcc/testsuite/c-c++-common/tsan/race_on_mutex2.c b/gcc/testsuite/c-c++-common/tsan/race_on_mutex2.c
new file mode 100644
index 000..d8a6980
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/tsan/race_on_mutex2.c
@@ -0,0 +1,26 @@
+/* { dg-do run } */
+/* { dg-shouldfail "tsan" } */
+
+#include 
+#include 
+#include 
+#include 
+
+void *Thread(void *x) {
+  pthread_mutex_lock((pthread_mutex_t*)x);
+  pthread_mutex_unlock((pthread_mutex_t*)x);
+  return 0;
+}
+
+int main() {
+  pthread_mutex_t Mtx;
+  pthread_mutex_init(&Mtx, 0);
+  pthread_t t;
+  pthread_create(&t, 0, Thread, &Mtx);
+  sleep(1);
+  pthread_mutex_destroy(&Mtx);
+  pthread_join(t, 0);
+  return 0;
+}
+
+/* { dg-output "WARNING: ThreadSanitizer: data race.*(\n|\r\n|\r)" } */
diff --git a/gcc/testsuite/c-c++-common/tsan/simple_race.c b/gcc/testsuite/c-c++-common/tsan/simple_race.c
new file mode 100644
index 000..24b88e8
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/tsan/simple_race.c
@@ -0,0 +1,28 @@
+/* { dg-do run } */
+/* { dg-shouldfail "tsan" } */
+
+#include 
+#include 
+
+int Global;
+
+void *Thread1(void *x) {
+  Global = 42;
+  return NULL;
+}
+
+void *Thread2(void *x) {
+  Global = 43;
+  return NULL;
+}
+
+int main() {
+  pthread_t t[2];
+  pthread_create(&t[0], NULL, Thread1, NULL);
+  pthread_create(&t[1], NULL, Thread2, NULL);
+  pthread_join(t[0], NULL);
+  pthread_join(t[1], NULL);
+  return 0;
+}
+
+/* { dg-output "WARNING: ThreadSanitizer: data race.*(\n|\r\n|\r)" } */
diff --git a/gcc/testsuite/c-c++-common/tsan/simple_stack.c b/gcc/testsuite/c-c++-common/tsan/simple_stack.c
new file

Re: New tsan tests.

2013-12-12 Thread Maxim Ostapenko

> Anyway, let's keep the current tests as is, the patch is ok for trunk.

Commited in 205925.


Re: RFC Asan instrumentation control

2013-12-18 Thread Maxim Ostapenko

Hi all,

On 12/06/2013 05:32 PM, Yury Gribov wrote:


So it looks like people are generally ok with
* --param asan-instrument-reads=0/1
* --param asan-instrument-writes=0/1
* --param asan-stack=0/1
* --param asan-globals=0/1

I've implemented these options. Tested on x86_64.

* --param asan-memintrin=0/1
but not with blacklists (which is sad but understandable).

-Y


This one will be implemented in future.

I've also added 4 new testfiles to test new options.

Can you review this patch, please?

-Maxim
2013-12-18  Max Ostapenko  

	* gcc/asan.c (asan_emit_stack_protection): Optionally disable stack protection.
	(instrument_derefs): Optionally disable memory access instrumentation.
	(instrument_mem_region_access): Likewise.
	(instrument_strlen_call): Likewise.
	(asan_finish_file): Optionally disable global variables protection.
	* gcc/doc/invoke.texi: Added doc for new options.
	* gcc/params.def: Added new options.
	* gcc/params.h: Likewise.

2013-12-18  Max Ostapenko  
	* c-c++-common/asan/global-overflow-2.c: New test.
	* c-c++-common/asan/memcmp-3.c: Likewise.
	* c-c++-common/asan/no-instrument-reads.c: Likewise.
	* c-c++-common/asan/no-instrument-writes.c: Likewise.

diff --git a/gcc/asan.c b/gcc/asan.c
index 1394e13..1b8d0c2 100644
--- a/gcc/asan.c
+++ b/gcc/asan.c
@@ -53,6 +53,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "gimple-builder.h"
 #include "ubsan.h"
 #include "predict.h"
+#include "params.h"
 
 /* AddressSanitizer finds out-of-bounds and use-after-free bugs
with <2x slowdown on average.
@@ -963,6 +964,9 @@ rtx
 asan_emit_stack_protection (rtx base, rtx pbase, unsigned int alignb,
 			HOST_WIDE_INT *offsets, tree *decls, int length)
 {
+  if (!ASAN_STACK)
+return NULL_RTX;
+
   rtx shadow_base, shadow_mem, ret, mem, orig_base, lab;
   char buf[30];
   unsigned char shadow_bytes[4];
@@ -1568,6 +1572,11 @@ static void
 instrument_derefs (gimple_stmt_iterator *iter, tree t,
 		   location_t location, bool is_store)
 {
+  if (is_store && !ASAN_INSTRUMENT_WRITES)
+return;
+  if (!is_store && !ASAN_INSTRUMENT_READS)
+return;
+
   tree type, base;
   HOST_WIDE_INT size_in_bytes;
 
@@ -1662,6 +1671,11 @@ instrument_mem_region_access (tree base, tree len,
 			  gimple_stmt_iterator *iter,
 			  location_t location, bool is_store)
 {
+  if (is_store && !ASAN_INSTRUMENT_WRITES)
+return;
+  if (!is_store && !ASAN_INSTRUMENT_READS)
+return;
+
   if (!POINTER_TYPE_P (TREE_TYPE (base))
   || !INTEGRAL_TYPE_P (TREE_TYPE (len))
   || integer_zerop (len))
@@ -1825,6 +1839,9 @@ instrument_mem_region_access (tree base, tree len,
 static bool
 instrument_strlen_call (gimple_stmt_iterator *iter)
 {
+  if (!ASAN_INSTRUMENT_READS)
+return false;
+
   gimple call = gsi_stmt (*iter);
   gcc_assert (is_gimple_call (call));
 
@@ -2396,7 +2413,7 @@ asan_finish_file (void)
   ++gcount;
   htab_t const_desc_htab = constant_pool_htab ();
   htab_traverse (const_desc_htab, count_string_csts, &gcount);
-  if (gcount)
+  if (gcount && ASAN_GLOBALS)
 {
   tree type = asan_global_struct (), var, ctor;
   tree dtor_statements = NULL_TREE;
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 99ec1d2..d1f20a9 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -10037,6 +10037,26 @@ The default choice depends on the target.
 Set the maximum number of existing candidates that will be considered when
 seeking a basis for a new straight-line strength reduction candidate.
 
+@item asan-globals
+Enable overflow/underflow detection for global objects. This kind of protection
+is enabled by default if you are using @option{-fsanitize=address} option.
+To disable global objects protection use @option{--param asan-globals=0} option.
+
+@item asan-stack
+Enable overflow/underflow detection for stack objects. This kind of protection
+is enabled by default if you are using @option{-fsanitize=address} option.
+To disable stack protection use @option{--param asan-stack=0} option.
+
+@item asan-instrument-reads
+Enable overflow/underflow detection for memory reads instructions. This kind of protection
+is enabled by default if you are using @option{-fsanitize=address} option.
+To disable memory reads instructions protection use @option{--param asan-instrument-reads=0} option.
+
+@item asan-instrument-writes
+Enable overflow/underflow detection for memory writes instructions. This kind of protection
+is enabled by default if you are using @option{-fsanitize=address} option.
+To disable memory writes instructions protection use @option{--param asan-instrument-writes=0} option.
+
 @end table
 @end table
 
diff --git a/gcc/params.def b/gcc/params.def
index c0f9622..aea5f41 100644
--- a/gcc/params.def
+++ b/gcc/params.def
@@ -1049,6 +1049,26 @@ DEFPARAM (PARAM_MAX_SLSR_CANDIDATE_SCAN,
 	  "strength reduction",
 	  50, 1, 99)
 
+DEFPARAM(PARAM_ASAN_STACK,
+ "asan-stack",
+ "Enable asan stack protection",
+ 1, 0, 1)
+
+DEFP

Re: RFC Asan instrumentation control

2013-12-19 Thread Maxim Ostapenko



2013-12-18 Max Ostapenko

* gcc/asan.c (asan_emit_stack_protection): Optionally disable 
stack protection.
(instrument_derefs): Optionally disable memory access 
instrumentation.

(instrument_mem_region_access): Likewise.
(instrument_strlen_call): Likewise.
(asan_finish_file): Optionally disable global variables protection.
* gcc/doc/invoke.texi: Added doc for new options.
* gcc/params.def: Added new options.
* gcc/params.h: Likewise.

> No gcc/ prefixes in ChangeLog entries.

Thanks, fixed.

--- a/gcc/asan.c
+++ b/gcc/asan.c
@@ -53,6 +53,7 @@ along with GCC; see the file COPYING3.  If not see
  #include "gimple-builder.h"
  #include "ubsan.h"
  #include "predict.h"
+#include "params.h"
/* AddressSanitizer finds out-of-bounds and use-after-free bugs
 with <2x slowdown on average.
@@ -963,6 +964,9 @@ rtx
  asan_emit_stack_protection (rtx base, rtx pbase, unsigned int alignb,
  HOST_WIDE_INT *offsets, tree *decls, int length)
  {
+  if (!ASAN_STACK)
+return NULL_RTX;

> This is a wrong spot to do this.  Instead put it into the
> if ((flag_sanitize & SANITIZE_ADDRESS) && pred)
> condition in cfgexpand.c (and maybe also
> if ((flag_sanitize & SANITIZE_ADDRESS) && isize != jsize ...)
> too, maybe all four flag_sanitize & SANITIZE_ADDRESS occurrences in
> cfgexpand.c.

Moved this check to cfgexpand.c.


@@ -2396,7 +2413,7 @@ asan_finish_file (void)
++gcount;
htab_t const_desc_htab = constant_pool_htab ();
htab_traverse (const_desc_htab, count_string_csts, &gcount);
-  if (gcount)
+  if (gcount && ASAN_GLOBALS)
  {
tree type = asan_global_struct (), var, ctor;
tree dtor_statements = NULL_TREE;


> I'd say this isn't sufficient, for !ASAN_GLOBALS you should also make 
sure
> asan_protect_global always returns false, so that no extra padding is 
emitted

> around the global vars.

Moved globals protection check to asan_protect_global.

> Talking about this, perhaps there should be also
> --param asan-use-after-return=0
> knob to disallow the support for use-after-return checking (in 4.8 this
> didn't exist, in 4.9 there is some extra runtime code emitted, but 
still one
> needs to enable it manually through environment variable). With that 
param
> we would emit pretty much what 4.8 did, i.e. assume that 
use-after-return

> will not be enabled in the runtime.


Added this option and also implemented asan-memintrin option.
Is it OK?

-Maxim


Re: RFC Asan instrumentation control

2013-12-19 Thread Maxim Ostapenko

Sorry, ChangeLog and patch, of course.

-Maxim.
2013-12-19  Max Ostapenko  

	* cfgexpand.c (expand_stack_vars): Optionally disable asan stack protection.
	(expand_used_vars): Likewise.
	(partition_stack_vars): Likewise.
	* asan.c (asan_emit_stack_protection): Optionally disable after return stack usage.
	(instrument_derefs): Optionally disable memory access instrumentation.
	(instrument_builtin_call): Likewise.
	(instrument_strlen_call): Likewise.
	(asan_protect_global): Optionally disable global variables protection.
	* doc/invoke.texi: Added doc for new options.
	* params.def: Added new options.
	* params.h: Likewise.

2013-12-19  Max Ostapenko  
	* c-c++-common/asan/global-overflow-2.c: New test.
	* c-c++-common/asan/memcmp-3.c: Likewise.
	* c-c++-common/asan/no-instrument-reads.c: Likewise.
	* c-c++-common/asan/no-instrument-writes.c: Likewise.
	* c-c++-common/asan/stack-use-after-return.c: Likewise
	* c-c++-common/asan/no-stack-use-after-return.c: Likewise.

diff --git a/gcc/asan.c b/gcc/asan.c
index 1394e13..005db18 100644
--- a/gcc/asan.c
+++ b/gcc/asan.c
@@ -53,6 +53,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "gimple-builder.h"
 #include "ubsan.h"
 #include "predict.h"
+#include "params.h"
 
 /* AddressSanitizer finds out-of-bounds and use-after-free bugs
with <2x slowdown on average.
@@ -1003,7 +1004,7 @@ asan_emit_stack_protection (rtx base, rtx pbase, unsigned int alignb,
   str_cst = asan_pp_string (&asan_pp);
 
   /* Emit the prologue sequence.  */
-  if (asan_frame_size > 32 && asan_frame_size <= 65536 && pbase)
+  if (asan_frame_size > 32 && asan_frame_size <= 65536 && pbase && ASAN_USE_AFTER_RETURN)
 {
   use_after_return_class = floor_log2 (asan_frame_size - 1) - 5;
   /* __asan_stack_malloc_N guarantees alignment
@@ -1239,6 +1240,9 @@ asan_needs_local_alias (tree decl)
 bool
 asan_protect_global (tree decl)
 {
+  if (!ASAN_GLOBALS)
+return false;
+
   rtx rtl, symbol;
 
   if (TREE_CODE (decl) == STRING_CST)
@@ -1568,6 +1572,11 @@ static void
 instrument_derefs (gimple_stmt_iterator *iter, tree t,
 		   location_t location, bool is_store)
 {
+  if (is_store && !ASAN_INSTRUMENT_WRITES)
+return;
+  if (!is_store && !ASAN_INSTRUMENT_READS)
+return;
+
   tree type, base;
   HOST_WIDE_INT size_in_bytes;
 
@@ -1897,6 +1906,9 @@ instrument_strlen_call (gimple_stmt_iterator *iter)
 static bool
 instrument_builtin_call (gimple_stmt_iterator *iter)
 {
+  if (!ASAN_MEMINTRIN)
+return false;
+
   bool iter_advanced_p = false;
   gimple call = gsi_stmt (*iter);
 
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index 7a93975..55708eb 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -798,7 +798,7 @@ partition_stack_vars (void)
 	 sizes, as the shorter vars wouldn't be adequately protected.
 	 Don't do that for "large" (unsupported) alignment objects,
 	 those aren't protected anyway.  */
-	  if ((flag_sanitize & SANITIZE_ADDRESS) && isize != jsize
+	  if ((flag_sanitize & SANITIZE_ADDRESS) && ASAN_STACK  && isize != jsize
 	  && ialign * BITS_PER_UNIT <= MAX_SUPPORTED_STACK_ALIGNMENT)
 	break;
 
@@ -981,7 +981,7 @@ expand_stack_vars (bool (*pred) (size_t), struct stack_vars_data *data)
   if (alignb * BITS_PER_UNIT <= MAX_SUPPORTED_STACK_ALIGNMENT)
 	{
 	  base = virtual_stack_vars_rtx;
-	  if ((flag_sanitize & SANITIZE_ADDRESS) && pred)
+	  if ((flag_sanitize & SANITIZE_ADDRESS) && ASAN_STACK && pred)
 	{
 	  HOST_WIDE_INT prev_offset = frame_offset;
 	  tree repr_decl = NULL_TREE;
@@ -1160,7 +1160,7 @@ defer_stack_allocation (tree var, bool toplevel)
   /* If stack protection is enabled, *all* stack variables must be deferred,
  so that we can re-order the strings to the top of the frame.
  Similarly for Address Sanitizer.  */
-  if (flag_stack_protect || (flag_sanitize & SANITIZE_ADDRESS))
+  if (flag_stack_protect || ((flag_sanitize & SANITIZE_ADDRESS) && ASAN_STACK))
 return true;
 
   /* We handle "large" alignment via dynamic allocation.  We want to handle
@@ -1820,7 +1820,7 @@ expand_used_vars (void)
 	expand_stack_vars (stack_protect_decl_phase_2, &data);
 	}
 
-  if (flag_sanitize & SANITIZE_ADDRESS)
+  if ((flag_sanitize & SANITIZE_ADDRESS) && ASAN_STACK)
 	/* Phase 3, any partitions that need asan protection
 	   in addition to phase 1 and 2.  */
 	expand_stack_vars (asan_decl_phase_3, &data);
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 1a6d815..f25958b 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -10037,6 +10037,36 @@ The default choice depends on the target.
 Set the maximum number of existing candidates that will be considered when
 seeking a basis for a new straight-line strength reduction candidate.
 
+@item asan-globals
+Enable buffer overflow detection for global objects. This kind of protection
+is enabled by default if you are using @option{-fsanitize=address} option.
+To disable global objects protection use @option{--param asan-

Re: RFC Asan instrumentation control

2013-12-24 Thread Maxim Ostapenko


On 12/19/2013 04:27 PM, Jakub Jelinek wrote:

On Thu, Dec 19, 2013 at 04:02:47PM +0400, Maxim Ostapenko wrote:

Sorry, ChangeLog and patch, of course.
2013-12-19  Max Ostapenko  

* cfgexpand.c (expand_stack_vars): Optionally disable asan stack 
protection.

Too long lines in ChangeLog, wrap to 80 columns.


Thanks, fixed.


(expand_used_vars): Likewise.
(partition_stack_vars): Likewise.
* asan.c (asan_emit_stack_protection): Optionally disable after return 
stack usage.

Ditto.


Likewise.


(instrument_derefs): Optionally disable memory access instrumentation.
(instrument_builtin_call): Likewise.
(instrument_strlen_call): Likewise.
(asan_protect_global): Optionally disable global variables protection.
* doc/invoke.texi: Added doc for new options.
* params.def: Added new options.
* params.h: Likewise.

2013-12-19  Max Ostapenko  
* c-c++-common/asan/global-overflow-2.c: New test.

Missing vertical space between date/name/mail and first entry.


Done.


@@ -1003,7 +1004,7 @@ asan_emit_stack_protection (rtx base, rtx pbase, unsigned 
int alignb,
str_cst = asan_pp_string (&asan_pp);
  
/* Emit the prologue sequence.  */

-  if (asan_frame_size > 32 && asan_frame_size <= 65536 && pbase)
+  if (asan_frame_size > 32 && asan_frame_size <= 65536 && pbase && 
ASAN_USE_AFTER_RETURN)
  {
use_after_return_class = floor_log2 (asan_frame_size - 1) - 5;
/* __asan_stack_malloc_N guarantees alignment

Please wrap this.


Done.


--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -798,7 +798,7 @@ partition_stack_vars (void)
 sizes, as the shorter vars wouldn't be adequately protected.
 Don't do that for "large" (unsupported) alignment objects,
 those aren't protected anyway.  */
- if ((flag_sanitize & SANITIZE_ADDRESS) && isize != jsize
+ if ((flag_sanitize & SANITIZE_ADDRESS) && ASAN_STACK  && isize != 
jsize

Replace the two spaces with just one.


Done.


--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -10037,6 +10037,36 @@ The default choice depends on the target.
  Set the maximum number of existing candidates that will be considered when
  seeking a basis for a new straight-line strength reduction candidate.
  
+@item asan-globals

+Enable buffer overflow detection for global objects. This kind of protection
+is enabled by default if you are using @option{-fsanitize=address} option.
+To disable global objects protection use @option{--param asan-globals=0} 
option.

Too long lines (several times).


Done.


+To disable memory reads instructions protection use @option{--param 
asan-instrument-reads=0} option.
+
+@item asan-instrument-writes
+Enable buffer overflow detection for memory writes instructions. This kind of 
protection
+is enabled by default if you are using @option{-fsanitize=address} option.
+To disable memory writes instructions protection use @option{--param 
asan-instrument-writes=0} option.
+
+@item asan-memintrin
+Enable detection for builtin functions. This kind of protection

I think for docs it should be "built-in functions".


Done.


As for the tests, I'm afraid I don't like them at all.
If anything, it ought to be dg-do compile tests where you say
scan assembly or some dump, but having runtime testcases that
trigger undefined behavior that isn't detected by the instrumentation
library at all and expect them to "pass" is simply wrong.

Jakub

Got it, converted all tests except no-asan-stack.c, because i failed to 
discover how to grep for stack

instrumentation. Perhaps memcmp of random data is fine?
2013-12-24  Max Ostapenko  

	* cfgexpand.c (expand_stack_vars): Optionally disable 
	asan stack protection.
	(expand_used_vars): Likewise.
	(partition_stack_vars): Likewise.
	* asan.c (asan_emit_stack_protection): Optionally disable 
	after return stack usage.
	(instrument_derefs): Optionally disable memory 
	access instrumentation.
	(instrument_builtin_call): Likewise.
	(instrument_strlen_call): Likewise.
	(asan_protect_global): Optionally disable 
	global variables protection.
	* doc/invoke.texi: Added doc for new options.
	* params.def: Added new options.
	* params.h: Likewise.

2013-12-24  Max Ostapenko  

	* c-c++-common/asan/no-asan-globals.c: New test.
	* c-c++-common/asan/no-asan-stack.c: Likewise.
	* c-c++-common/asan/no-instrument-reads.c: Likewise.
	* c-c++-common/asan/no-instrument-writes.c: Likewise.
	* c-c++-common/asan/use-after-return-1.c: Likewise.
	* c-c++-common/asan/no-use-after-return.c: Likewise.


diff --git a/gcc/asan.c b/gcc/asan.c
index d4059d6..1d9d8ae 100644
--- a/gcc/asan.c
+++ b/gcc/asan.c
@@ -53,6 +53,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "gimple-builder.h"
 #include "ubsan.h&

Re: RFC Asan instrumentation control

2014-01-09 Thread Maxim Ostapenko

Hi!

>> * c-c++-common/asan/no-asan-stack.c (this triggers read overflow
>> because we haven't found a cross-platform way to grep for stack
>> redzones instrumentation)

> I'd prefer no test in that case, or just some semi-platform specific 
test
> (scan that the 0x41b58ab3 constant doesn't appear in say some late 
RTL dump,
> or perhaps just assembly (just scan it with lower and upper case and 
decimal

> too)).

Thanks, commited in 206458 without c-c++-common/asan/no-asan-stack.c 
testfile.

I'll fix this test according to your recommendations a bit later.

-Maxim.


Re: RFC Asan instrumentation control

2014-01-09 Thread Maxim Ostapenko

Hi!

>>> * c-c++-common/asan/no-asan-stack.c (this triggers read overflow
>>> because we haven't found a cross-platform way to grep for stack
>>> redzones instrumentation)
>>
>> I'd prefer no test in that case, or just some semi-platform specific 
test
>> (scan that the 0x41b58ab3 constant doesn't appear in say some late 
RTL dump,
>> or perhaps just assembly (just scan it with lower and upper case and 
decimal

>> too)).
>
> Thanks, commited in 206458 without c-c++-common/asan/no-asan-stack.c 
testfile.

> I'll fix this test according to your recommendations a bit later.

I've fixed the c-c++-common/asan/no-asan-stack.c testfile. Tested on
x86_64-unknown-linux-gnu.

Ok to commit?

-Maxim.
2014-01-10  Max Ostapenko  

	* c-c++-common/asan/no-asan-stack.c: New test.

diff --git a/gcc/testsuite/c-c++-common/asan/no-asan-stack.c b/gcc/testsuite/c-c++-common/asan/no-asan-stack.c
new file mode 100644
index 000..d81b834
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/asan/no-asan-stack.c
@@ -0,0 +1,17 @@
+/* { dg-do assemble { target { x86_64-unknown-linux-gnu } } } */
+/* { dg-options "-save-temps --param asan-stack=0" } */
+#include 
+
+volatile int one = 1;
+
+int
+main ()
+{
+  volatile char a1[] = {one, 2, 3, 4};
+  volatile char a2[] = {1, 2*one, 3, 4};
+  volatile int res = memcmp ((void *)a1,(void *)a2, 5 + one);
+  return 0;
+}
+
+/* { dg-final { scan-assembler-not "0x41b58ab3|0x41B58AB3|1102416563" } } */
+/* { dg-final { cleanup-saved-temps } } */


Re: RFC Asan instrumentation control

2014-01-10 Thread Maxim Ostapenko

If you want to limit to x86_64-linux only, please do:
target { { i?86-*-linux* x86_64-*-linux* } && lp64 }
instead.  Also, what advantages do you see for trying to assemble
the result?  If you instead just do dg-do compile, you can drop -save-temps
from dg-options and /* { dg-final { cleanup-saved-temps } } */.


Thanks, got it. Is it OK now?

-Maxim.

2014-01-10  Max Ostapenko  

	* c-c++-common/asan/no-asan-stack.c: New test.

diff --git a/gcc/testsuite/c-c++-common/asan/no-asan-stack.c b/gcc/testsuite/c-c++-common/asan/no-asan-stack.c
new file mode 100644
index 000..0f65ab3
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/asan/no-asan-stack.c
@@ -0,0 +1,16 @@
+/* { dg-do compile { target { { i?86-*-linux* x86_64-*-linux* } && lp64 } } } */
+/* { dg-options "--param asan-stack=0" } */
+#include 
+
+volatile int one = 1;
+
+int
+main ()
+{
+  volatile char a1[] = {one, 2, 3, 4};
+  volatile char a2[] = {1, 2*one, 3, 4};
+  volatile int res = memcmp ((void *)a1,(void *)a2, 5 + one);
+  return 0;
+}
+
+/* { dg-final { scan-assembler-not "0x41b58ab3|0x41B58AB3|1102416563" } } */


Re: RFC Asan instrumentation control

2014-01-10 Thread Maxim Ostapenko


On 01/10/2014 12:36 PM, Jakub Jelinek wrote:

On Fri, Jan 10, 2014 at 12:34:49PM +0400, Maxim Ostapenko wrote:

Thanks, got it. Is it OK now?

Yes, thanks.


2014-01-10  Max Ostapenko  

* c-c++-common/asan/no-asan-stack.c: New test.

Jakub

Commited in 206515.

-Maxim.


Re: libsanitizer merge from upstream r196090

2014-01-10 Thread Maxim Ostapenko


Hi all,

On Fri, Jan 10, 2014 at 10:39 AM, Jakub Jelinek wrote:

> Some of the tsan tests seems to FAIL randomly for quite a while
> (since they  were added), didn't have time to look if it is just bugs 
in the test or

> some compiler issue or library issue.

When I've commited these tsan tests, all of them were passed on my
x86_64-unknown-linux-gnu 64bit system.

Should I review them more carefully?

-Maxim.


[RFC, PATCH] Disable -fprofile-use related optimizations if corresponding .gcda file not found.

2015-10-07 Thread Maxim Ostapenko

Hi,

when testing OpenSSL performance, I found out that sometimes PGO-built 
binaries can actually introduce performance regressions. We could 
identify affected object files and disable PGO for them by simply 
removing corresponding .gcda file. However, even if profile data is not 
presented, GCC doesn't switch back -fprofile-use dependent optimizations 
(e.g. -fbranch-probabilities, -fvpt, etc). This may also lead to 
performance degradations.


The issue had already raised quite time ago 
(https://gcc.gnu.org/ml/gcc-patches/2009-09/msg02119.html), but for some 
reasons wasn't discussed.


Here a draft patch that disables -fprofile-use related optimizations if 
profile data wasn't found (perhaps it makes sense to introduce a special 
switch for this?). Does this look reasonable?


Thanks,
-Maxim
gcc/ChangeLog:

2015-10-07  Maxim Ostapenko  

	* coverage.c (disable_profile_use_flags): New function.
	(read_counts_file): Call it if corresponding .gcda file wasn't found.

diff --git a/gcc/coverage.c b/gcc/coverage.c
index 4c06fa4..37e16b7 100644
--- a/gcc/coverage.c
+++ b/gcc/coverage.c
@@ -134,6 +134,7 @@ static bool coverage_obj_init (void);
 static vec *coverage_obj_fn
 (vec *, tree, struct coverage_data const *);
 static void coverage_obj_finish (vec *);
+static void disable_profile_use_flags (void);
 
 /* Return the type node for gcov_type.  */
 
@@ -190,7 +191,10 @@ read_counts_file (void)
   unsigned cfg_checksum = 0;
 
   if (!gcov_open (da_file_name, 1))
-return;
+{
+  disable_profile_use_flags ();
+  return;
+}
 
   if (!gcov_magic (gcov_read_unsigned (), GCOV_DATA_MAGIC))
 {
@@ -1219,4 +1223,14 @@ coverage_finish (void)
   da_file_name = NULL;
 }
 
+/* Reset flags if a .gcda file is not found.  */ 
+static void
+disable_profile_use_flags (void)
+{
+  flag_branch_probabilities = flag_profile_values = flag_unroll_loops = false;
+  flag_value_profile_transformations
+   = flag_tree_loop_distribute_patterns = false;
+  flag_rename_registers = flag_peel_loops = false;
+  flag_profile_reorder_functions = flag_tracer = false;
+}
+
 #include "gt-coverage.h"


Re: [RFC, PATCH] Disable -fprofile-use related optimizations if corresponding .gcda file not found.

2015-10-07 Thread Maxim Ostapenko



On 07/10/15 19:18, Andrew Pinski wrote:

On Wed, Oct 7, 2015 at 9:11 AM, Maxim Ostapenko
 wrote:

Hi,

when testing OpenSSL performance, I found out that sometimes PGO-built
binaries can actually introduce performance regressions. We could identify
affected object files and disable PGO for them by simply removing
corresponding .gcda file. However, even if profile data is not presented,
GCC doesn't switch back -fprofile-use dependent optimizations (e.g.
-fbranch-probabilities, -fvpt, etc). This may also lead to performance
degradations.

The issue had already raised quite time ago
(https://gcc.gnu.org/ml/gcc-patches/2009-09/msg02119.html), but for some
reasons wasn't discussed.

Here a draft patch that disables -fprofile-use related optimizations if
profile data wasn't found (perhaps it makes sense to introduce a special
switch for this?). Does this look reasonable?

I thought if profile is not present, then branch probabilities goes
back to the original heuristics?
Which option is really causing the performance degradation here?


-fprofile-use enabled -fpeel-loops that in turn enabled 
-frename-registers. This caused the scheduler to transform the code in 
sched2 pass.



Also I think your patch is very incomplete as someone could use
-frename-registers with -fprofile-use and then you just turned it off.

Thanks,
Andrew Pinski


Doesn't -fprofile-use enable -frename-registers transitively through 
-fpeel-loops?



Thanks,
-Maxim




[PATCH] Fix another bootstrap-ubsan failure due to -Werror=maybe-uninitialized.

2015-10-08 Thread Maxim Ostapenko

Hi,

running UBSan bootstrap on trunk, I've run to the such issue:

/home/max/workspace/downloads/svn/trunk/gcc/fortran/parse.c: In function 
‘gfc_statement decode_statement()’:
/home/max/workspace/downloads/svn/trunk/gcc/fortran/parse.c:368:51: 
error: ‘m’ may be used uninitialized in this function 
[-Werror=maybe-uninitialized]

   if (!(in_specification_block && m == MATCH_ERROR))

Actually, the situation is pretty much similar to PR sanitizer/67867 
fixed by Marek in r228569. This tiny patch just initializes m with 
MATCH_NO value.
By fixing this, UBSan bootstrap can proceed, although I see some errors 
detected (will report them later).


Is this OK for trunk?

-Maxim
gcc/fortran/ChangeLog:

2015-10-08  Maxim Ostapenko  

	* parse.c (decode_statement): Initialize M to MATCH_NO.

diff --git a/gcc/fortran/parse.c b/gcc/fortran/parse.c
index 6f3d24b..4925c7e 100644
--- a/gcc/fortran/parse.c
+++ b/gcc/fortran/parse.c
@@ -296,7 +296,7 @@ decode_statement (void)
   gfc_namespace *ns;
   gfc_statement st;
   locus old_locus;
-  match m;
+  match m = MATCH_NO;
   char c;
 
   gfc_enforce_clean_symbol_state ();


[PATCH 0/7] Libsanitizer merge from upstream r249633.

2015-10-13 Thread Maxim Ostapenko

Hi,

it's been a while since the last libsanitizer merge from upstream into 
GCC happened and the library has significantly changed since that time. 
The main features to be ported are:


-New common strings interceptors were added.
-Various allocator improvements were performed.
-Improvements for ASan deactivated start were performed.
-TSan and LSan were enabled for Aarch64.
-Fast unwinding was enabled for Aarch64.
-New tsan_unaligned_{load, store}_[n] functions were intoduced.
-asan_stack_malloc_[n] doesn't take a local stack as a second parameter 
anymore.

-sanitization for std containers is supported now.
-New interface functions for dynamic allocas and VLA's 
poisoning/unpoisoning were introduced.


Some features are not ported for now, by might be enabled in future:

-Embedded UBSan runtime into ASan and TSan ones. I don't enable this 
now, because of errors during ASan static linkage: GCC uses 
-whole-archive option that would lead to undefined references to C++ stuff.
-UBSan data descriptors for float-cast conversion support location 
propagation now. But sometimes we have loc == UNKNOWN_LOCATION in 
ubsan_instrument_float_cast, so use old ABI for now. See below for details.


The first patch of the series is the merge itself.

The second one introduces corresponding compiler changes.

Other patches are applied to library and they are GCC-specific:

Patches 3 and 4 are just reapplied David's and Jakub's patches for SPARC 
and disabling ODR violation detection respectively.


Patch 5 removes UBSan stubs from ASan and TSan code since we don't 
support embedded UBSan runtime into ASan and TSan.


Patch 6 changes heuristic for extracting last PC from stack frame for 
ARM in fast unwind routine. More details can be found here 
(https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61771).


Patch 7 forces libsanitizer to use an old ABI for ubsan float cast data 
descriptors, because sometimes we can have loc == UNKNOWN_LOCATION in 
ubsan_instrument_float_cast e.g. in a such case:


..
volatile double foo; // ubsan_instrument_float_cast is called by convert 
function.

..

Since foo is a tcc_declaration, loc is UNKNOWN_LOCATION. I'm actually 
not sure about this, perhaps we can fix this in GCC somehow.


I've regtested and {A, UB}San bootstrapped these patches on 
x86-64-unknown-linux-gnu and aarch64-linux-gnueabi (Juno board, 39 bit 
VA space) and tested for ARM under QEMU-ARM.
Testing ASan under QEMU-AARCH64 revealed many test failures due to LSan 
was enabled. In particular, it tries to call internal_clone function in 
LSan internals, that in turn calls _NR_clone syscall and than QEMU exits 
with EINTR error code (that might be expected, AFAIK QEMU is not very 
good with threads). So, I wonder, if I should disable LSan for AArch64 now?


I'm also asking community to help me with testing these patches on 
various targets (ARM, PPC, etc) I'm lack of, so could you help me on 
this please?


-Maxim


[PATCH 2/7] Libsanitizer merge from upstream r249633.

2015-10-13 Thread Maxim Ostapenko
This patch introduces required compiler changes. Now, we don't version 
asan_init, we have a special __asan_version_mismatch_check_v[n] symbol 
for this.


Also, asan_stack_malloc_[n] doesn't take a local stack as a second 
parameter anymore, so don't pass it.
2015-10-12  Maxim Ostapenko  

config/

	* bootstrap-asan.mk: Replace ASAN_OPTIONS=detect_leaks with
	LSAN_OPTIONS=detect_leaks

gcc/

	* asan.c (asan_emit_stack_protection): Don't pass local stack to
	asan_stack_malloc_[n] anymore.
	(asan_finish_file): Instert __asan_version_mismatch_check_v[n] call.
	* sanitizer.def (BUILT_IN_ASAN_INIT): Rename to __asan_init.
	(BUILT_IN_ASAN_VERSION_MISMATCH_CHECK): Add new builtin call.

gcc/testsuite/

	g++.dg/asan/default-options-1.C: Adjust testcase.

Index: gcc/asan.c
===
--- gcc/asan.c	(revision 228704)
+++ gcc/asan.c	(working copy)
@@ -1132,12 +1132,10 @@
   snprintf (buf, sizeof buf, "__asan_stack_malloc_%d",
 		use_after_return_class);
   ret = init_one_libfunc (buf);
-  rtx addr = convert_memory_address (ptr_mode, base);
-  ret = emit_library_call_value (ret, NULL_RTX, LCT_NORMAL, ptr_mode, 2,
+  ret = emit_library_call_value (ret, NULL_RTX, LCT_NORMAL, ptr_mode, 1,
  GEN_INT (asan_frame_size
 	  + base_align_bias),
- TYPE_MODE (pointer_sized_int_node),
- addr, ptr_mode);
+ TYPE_MODE (pointer_sized_int_node));
   ret = convert_memory_address (Pmode, ret);
   emit_move_insn (base, ret);
   emit_label (lab);
@@ -2470,6 +2468,8 @@
 {
   tree fn = builtin_decl_implicit (BUILT_IN_ASAN_INIT);
   append_to_statement_list (build_call_expr (fn, 0), &asan_ctor_statements);
+  fn = builtin_decl_implicit (BUILT_IN_ASAN_VERSION_MISMATCH_CHECK);
+  append_to_statement_list (build_call_expr (fn, 0), &asan_ctor_statements);
 }
   FOR_EACH_DEFINED_VARIABLE (vnode)
 if (TREE_ASM_WRITTEN (vnode->decl)
Index: gcc/sanitizer.def
===
--- gcc/sanitizer.def	(revision 228704)
+++ gcc/sanitizer.def	(working copy)
@@ -27,8 +27,11 @@
for other FEs by asan.c.  */
 
 /* Address Sanitizer */
-DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_INIT, "__asan_init_v4",
+DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_INIT, "__asan_init",
 		  BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST)
+DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_VERSION_MISMATCH_CHECK,
+		  "__asan_version_mismatch_check_v6",
+		  BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST)
 /* Do not reorder the BUILT_IN_ASAN_{REPORT,CHECK}* builtins, e.g. cfgcleanup.c
relies on this order.  */
 DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_REPORT_LOAD1, "__asan_report_load1",
Index: gcc/testsuite/g++.dg/asan/default-options-1.C
===
--- gcc/testsuite/g++.dg/asan/default-options-1.C	(revision 228704)
+++ gcc/testsuite/g++.dg/asan/default-options-1.C	(working copy)
@@ -12,4 +12,4 @@
   return 0;
 }
 
-// { dg-output "Using the defaults from __asan_default_options:.* foo=bar.*(\n|\r\n|\r)" }
+// { dg-output "WARNING: found 1 unrecognized flag\\(s\\):(\n|\r\n|\r).*foo(\n|\r\n|\r)" }


[PATCH 3/7] Libsanitizer merge from upstream r249633.

2015-10-13 Thread Maxim Ostapenko
This is just reapplied patch for SPARC by David S. Miller. I was unable 
to test this, so could anyone help me here?
2015-10-12  Maxim Ostapenko  

	PR sanitizer/63958
	Reapply:
	2015-03-09  Jakub Jelinek  

	PR sanitizer/63958
	Reapply:
	2014-10-14  David S. Miller  

	* sanitizer_common/sanitizer_platform_limits_linux.cc (time_t):
	Define at __kernel_time_t, as needed for sparc.
	(struct __old_kernel_stat): Don't check if __sparc__ is defined.
	* libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h
	(__sanitizer): Define struct___old_kernel_stat_sz,
	struct_kernel_stat_sz, and struct_kernel_stat64_sz for sparc.
	(__sanitizer_ipc_perm): Adjust for sparc targets.
	(__sanitizer_shmid_ds): Likewsie.
	(__sanitizer_sigaction): Likewise.
	(IOC_SIZE): Likewsie.

Index: libsanitizer/sanitizer_common/sanitizer_platform_limits_linux.cc
===
--- libsanitizer/sanitizer_common/sanitizer_platform_limits_linux.cc	(revision 250059)
+++ libsanitizer/sanitizer_common/sanitizer_platform_limits_linux.cc	(working copy)
@@ -38,6 +38,7 @@
 #define uid_t __kernel_uid_t
 #define gid_t __kernel_gid_t
 #define off_t __kernel_off_t
+#define time_t __kernel_time_t
 // This header seems to contain the definitions of _kernel_ stat* structs.
 #include 
 #undef ino_t
@@ -62,7 +63,7 @@
 }  // namespace __sanitizer
 
 #if !defined(__powerpc64__) && !defined(__x86_64__) && !defined(__aarch64__)\
-&& !defined(__mips__)
+&& !defined(__mips__) && !defined(__sparc__)
 COMPILER_CHECK(struct___old_kernel_stat_sz == sizeof(struct __old_kernel_stat));
 #endif
 
Index: libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h
===
--- libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h	(revision 250059)
+++ libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h	(working copy)
@@ -83,6 +83,14 @@
   const unsigned struct_kernel_stat_sz = 144;
   #endif
   const unsigned struct_kernel_stat64_sz = 104;
+#elif defined(__sparc__) && defined(__arch64__)
+  const unsigned struct___old_kernel_stat_sz = 0;
+  const unsigned struct_kernel_stat_sz = 104;
+  const unsigned struct_kernel_stat64_sz = 144;
+#elif defined(__sparc__) && !defined(__arch64__)
+  const unsigned struct___old_kernel_stat_sz = 0;
+  const unsigned struct_kernel_stat_sz = 64;
+  const unsigned struct_kernel_stat64_sz = 104;
 #endif
   struct __sanitizer_perf_event_attr {
 unsigned type;
@@ -105,7 +113,7 @@
 
 #if defined(__powerpc64__)
   const unsigned struct___old_kernel_stat_sz = 0;
-#else
+#elif !defined(__sparc__)
   const unsigned struct___old_kernel_stat_sz = 32;
 #endif
 
@@ -184,6 +192,18 @@
 unsigned short __pad1;
 unsigned long __unused1;
 unsigned long __unused2;
+#elif defined(__sparc__)
+# if defined(__arch64__)
+unsigned mode;
+unsigned short __pad1;
+# else
+unsigned short __pad1;
+unsigned short mode;
+unsigned short __pad2;
+# endif
+unsigned short __seq;
+unsigned long long __unused1;
+unsigned long long __unused2;
 #else
 unsigned short mode;
 unsigned short __pad1;
@@ -201,6 +221,26 @@
 
   struct __sanitizer_shmid_ds {
 __sanitizer_ipc_perm shm_perm;
+  #if defined(__sparc__)
+  # if !defined(__arch64__)
+u32 __pad1;
+  # endif
+long shm_atime;
+  # if !defined(__arch64__)
+u32 __pad2;
+  # endif
+long shm_dtime;
+  # if !defined(__arch64__)
+u32 __pad3;
+  # endif
+long shm_ctime;
+uptr shm_segsz;
+int shm_cpid;
+int shm_lpid;
+unsigned long shm_nattch;
+unsigned long __glibc_reserved1;
+unsigned long __glibc_reserved2;
+  #else
   #ifndef __powerpc__
 uptr shm_segsz;
   #elif !defined(__powerpc64__)
@@ -238,6 +278,7 @@
 uptr __unused4;
 uptr __unused5;
   #endif
+#endif
   };
 #elif SANITIZER_FREEBSD
   struct __sanitizer_ipc_perm {
@@ -555,9 +596,13 @@
 #else
 __sanitizer_sigset_t sa_mask;
 #ifndef __mips__
+#if defined(__sparc__)
+unsigned long sa_flags;
+#else
 int sa_flags;
 #endif
 #endif
+#endif
 #if SANITIZER_LINUX
 void (*sa_restorer)();
 #endif
@@ -799,7 +844,7 @@
 
 #define IOC_NRBITS 8
 #define IOC_TYPEBITS 8
-#if defined(__powerpc__) || defined(__powerpc64__) || defined(__mips__)
+#if defined(__powerpc__) || defined(__powerpc64__) || defined(__mips__) || defined(__sparc__)
 #define IOC_SIZEBITS 13
 #define IOC_DIRBITS 3
 #define IOC_NONE 1U
@@ -829,7 +874,17 @@
 #define IOC_DIR(nr) (((nr) >> IOC_DIRSHIFT) & IOC_DIRMASK)
 #define IOC_TYPE(nr) (((nr) >> IOC_TYPESHIFT) & IOC_TYPEMASK)
 #define IOC_NR(nr) (((nr) >> IOC_NRSHIFT) & IOC_NRMASK)
+
+#if defined(__sparc__)
+// In sparc the 14 bits SIZE field overlaps with the
+// least significant bit of DIR, so either IOC_READ or
+// IOC_WRITE shall be 1 in order to ge

[PATCH 4/7] Libsanitizer merge from upstream r249633.

2015-10-13 Thread Maxim Ostapenko
This is a reapplied Jakub's patch for disabling ODR violation detection. 
More details can be found here 
(https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63888).
2015-10-12  Maxim Ostapenko  

	PR bootstrap/63888
	Reapply:
	2015-02-20  Jakub Jelinek  

	* asan/asan_globals.cc (RegisterGlobal): Disable detect_odr_violation
	support until it is rewritten upstream.

	* c-c++-common/asan/pr63888.c: New test.

Index: libsanitizer/asan/asan_globals.cc
===
--- libsanitizer/asan/asan_globals.cc	(revision 250059)
+++ libsanitizer/asan/asan_globals.cc	(working copy)
@@ -146,7 +146,9 @@
   CHECK(AddrIsInMem(g->beg));
   CHECK(AddrIsAlignedByGranularity(g->beg));
   CHECK(AddrIsAlignedByGranularity(g->size_with_redzone));
-  if (flags()->detect_odr_violation) {
+  // This "ODR violation" detection is fundamentally incompatible with
+  // how GCC registers globals.  Disable as useless until rewritten upstream.
+  if (0 && flags()->detect_odr_violation) {
 // Try detecting ODR (One Definition Rule) violation, i.e. the situation
 // where two globals with the same name are defined in different modules.
 if (__asan_region_is_poisoned(g->beg, g->size_with_redzone)) {


[PATCH 5/7] Libsanitizer merge from upstream r249633.

2015-10-13 Thread Maxim Ostapenko
This patch removes UBSan stubs from ASan and TSan code. We don't embed 
UBSan to ASan and UBSan because that would lead to undefined references 
to C++ stuff when linking with -static-libasan. AFAIK, sanitizer 
developers use different libraries for C and CXX runtimes, but I think 
this is out of scope of this merge.
2015-10-13  Maxim Ostapenko  

	* tsan/tsan_defs.h: Define TSAN_CONTAINS_UBSAN to 0.
	* asan/asan_flags.cc (InitializeFlags): Do not initialize UBSan flags.
	* asan/asan_rtl.cc (AsanInitInternal): Do not init UBSan.

Index: libsanitizer/asan/asan_flags.cc
===
--- libsanitizer/asan/asan_flags.cc	(revision 250059)
+++ libsanitizer/asan/asan_flags.cc	(working copy)
@@ -86,15 +86,6 @@
   RegisterCommonFlags(&lsan_parser);
 #endif
 
-#if CAN_SANITIZE_UB
-  __ubsan::Flags *uf = __ubsan::flags();
-  uf->SetDefaults();
-
-  FlagParser ubsan_parser;
-  __ubsan::RegisterUbsanFlags(&ubsan_parser, uf);
-  RegisterCommonFlags(&ubsan_parser);
-#endif
-
   // Override from ASan compile definition.
   const char *asan_compile_def = MaybeUseAsanDefaultOptionsCompileDefinition();
   asan_parser.ParseString(asan_compile_def);
@@ -102,20 +93,11 @@
   // Override from user-specified string.
   const char *asan_default_options = MaybeCallAsanDefaultOptions();
   asan_parser.ParseString(asan_default_options);
-#if CAN_SANITIZE_UB
-  const char *ubsan_default_options = __ubsan::MaybeCallUbsanDefaultOptions();
-  ubsan_parser.ParseString(ubsan_default_options);
-#endif
-
   // Override from command line.
   asan_parser.ParseString(GetEnv("ASAN_OPTIONS"));
 #if CAN_SANITIZE_LEAKS
   lsan_parser.ParseString(GetEnv("LSAN_OPTIONS"));
 #endif
-#if CAN_SANITIZE_UB
-  ubsan_parser.ParseString(GetEnv("UBSAN_OPTIONS"));
-#endif
-
   // Let activation flags override current settings. On Android they come
   // from a system property. On other platforms this is no-op.
   if (!flags()->start_deactivated) {
Index: libsanitizer/asan/asan_rtl.cc
===
--- libsanitizer/asan/asan_rtl.cc	(revision 250059)
+++ libsanitizer/asan/asan_rtl.cc	(working copy)
@@ -513,10 +513,6 @@
   }
 #endif  // CAN_SANITIZE_LEAKS
 
-#if CAN_SANITIZE_UB
-  __ubsan::InitAsPlugin();
-#endif
-
   InitializeSuppressions();
 
   VReport(1, "AddressSanitizer Init done\n");
Index: libsanitizer/tsan/rtl/tsan_defs.h
===
--- libsanitizer/tsan/tsan_defs.h	(revision 250059)
+++ libsanitizer/tsan/tsan_defs.h	(working copy)
@@ -29,7 +29,7 @@
 #endif
 
 #ifndef TSAN_CONTAINS_UBSAN
-# define TSAN_CONTAINS_UBSAN (CAN_SANITIZE_UB && !defined(SANITIZER_GO))
+# define TSAN_CONTAINS_UBSAN 0
 #endif
 
 namespace __tsan {


[PATCH 6/7] Libsanitizer merge from upstream r249633.

2015-10-13 Thread Maxim Ostapenko
This patch adjusts the fix for 
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61771 to extract the last 
PC from the stack frame if no valid FP is available for ARM.
2015-10-13  Maxim Ostapenko  

	* sanitizer_common/sanitizer_stacktrace.cc (GetCanonicFrame): Assume we
	compiled code with GCC when extracting the caller PC for ARM if no
	valid frame pointer is available.

Index: libsanitizer/sanitizer_common/sanitizer_stacktrace.cc
===
--- libsanitizer/sanitizer_common/sanitizer_stacktrace.cc	(revision 250059)
+++ libsanitizer/sanitizer_common/sanitizer_stacktrace.cc	(working copy)
@@ -62,8 +62,8 @@
   // Nope, this does not look right either. This means the frame after next does
   // not have a valid frame pointer, but we can still extract the caller PC.
   // Unfortunately, there is no way to decide between GCC and LLVM frame
-  // layouts. Assume LLVM.
-  return bp_prev;
+  // layouts. Assume GCC.
+  return bp_prev - 1;
 #else
   return (uhwptr*)bp;
 #endif


[PATCH 7/7] Libsanitizer merge from upstream r249633.

2015-10-13 Thread Maxim Ostapenko
This is the final patch. Force libsanitizer to use an old ABI for ubsan 
float cast data descriptors, because for some exprs (e.g. that type of 
tcc_declaration) we can't get the right location for now. I'm not sure 
about this, perhaps it should be fixed in GCC somehow.
2015-10-13  Maxim Ostapenko  

	* ubsan/ubsan_handlers.cc (looksLikeFloatCastOverflowDataV1): Always
	return true for now.

Index: libsanitizer/ubsan/ubsan_handlers.cc
===
--- libsanitizer/ubsan/ubsan_handlers.cc	(revision 250059)
+++ libsanitizer/ubsan/ubsan_handlers.cc	(working copy)
@@ -307,6 +307,9 @@
 }
 
 static bool looksLikeFloatCastOverflowDataV1(void *Data) {
+  // (TODO): propagate SourceLocation into DataDescriptor and use this
+  // heuristic than.
+  return true;
   // First field is either a pointer to filename or a pointer to a
   // TypeDescriptor.
   u8 *FilenameOrTypeDescriptor;


Re: [PATCH 1/7] Libsanitizer merge from upstream r249633.

2015-10-14 Thread Maxim Ostapenko

On 14/10/15 10:54, Jakub Jelinek wrote:

On Tue, Oct 13, 2015 at 07:54:33PM +0300, Maxim Ostapenko wrote:

On 13/10/15 14:15, Maxim Ostapenko wrote:

This is the raw merge itself. I'm bumping SONAME to libasan.so.3.

-Maxim

I have just noticed that I've misused autoconf stuff (used wrong version).
Here a fixed version of the same patch. Sorry for inconvenience.

Is libubsan, libtsan backwards compatible, or do we want to change SONAME
there too?


No, they are not (for UBSan heuristic doesn't work well for GCC, TSan 
has some type changes into interceptors and data structures, e.g. in 
struct ReportStack). I  can share more details, if desired.




The aarch64 changes are terrible, not just because it doesn't yet have
runtime decision on what VA to use or that it doesn't support 48-bit VA,
but also that for the 42-bit VA it uses a different shadow offset from
39-bit VA.  But on the compiler side we have just one...
Though, only the 39-bit VA is enabled right now by default, so out of the
box the state is as bad as we had in 5.x - users wanting 42-bit VA or 48-bit
VA have to patch libsanitizer.

Have you verified libbacktrace sanitization still works properly (that is
something upstream does not test)?


I'm sorry, didn't catch well your words about libbacktrace sanitization. 
Did you mean symbolization? If so, I didn't perform any special 
validation here (thought output patterns tests use libbacktrace output, 
no?). But I wonder how can I verify this more or less automatically.




Do you plan to update the asan tests we have to reflect the changes in
upstream?


Hm, there aren't changes into instrumentation, so the only thing is new 
interceptors. If it is desirable, I can migrate some tests for new 
interceptors from upstream.




Jakub





Re: [PATCH 7/7] Libsanitizer merge from upstream r249633.

2015-10-14 Thread Maxim Ostapenko

On 14/10/15 10:48, Jakub Jelinek wrote:

On Tue, Oct 13, 2015 at 02:22:36PM +0300, Maxim Ostapenko wrote:

This is the final patch. Force libsanitizer to use an old ABI for ubsan
float cast data descriptors, because for some exprs (e.g. that type of
tcc_declaration) we can't get the right location for now. I'm not sure about
this, perhaps it should be fixed in GCC somehow.

I don't like this (neither the heuristics on the libubsan, it wouldn't be a
big deal to add a new library entrypoint).
If because of the heuristics you need to ensure that the SourceLocation is
always known, then either you check in ubsan.c whether expand_location
gives you NULL xloc.file and in that case use old style float cast overflow
(without location) - i.e. pass 0, NULL, otherwise you use new style, i.e.
pass 1, &loc.  Or arrange through some special option to emit something like
{ "", 0, 0 } instead of { NULL, 0, 0 } for the float cast case.
And, regardless of this, any progress in making sure we have fewer cases
with UNKNOWN_LOCATION on this will not hurt.  I think at this point I'd
prefer the first choice, i.e. using old style for locations without
filename, and new style otherwise.


2015-10-13  Maxim Ostapenko  

* ubsan/ubsan_handlers.cc (looksLikeFloatCastOverflowDataV1): Always
return true for now.

Index: libsanitizer/ubsan/ubsan_handlers.cc
===
--- libsanitizer/ubsan/ubsan_handlers.cc(revision 250059)
+++ libsanitizer/ubsan/ubsan_handlers.cc(working copy)
@@ -307,6 +307,9 @@
  }
  
  static bool looksLikeFloatCastOverflowDataV1(void *Data) {

+  // (TODO): propagate SourceLocation into DataDescriptor and use this
+  // heuristic than.
+  return true;
// First field is either a pointer to filename or a pointer to a
// TypeDescriptor.
u8 *FilenameOrTypeDescriptor;


Jakub



Ok, got it. The first solution would require changes in libsanitizer 
because heuristic doesn't work for GCC, so perhaps new UBSan entry point 
should go upstream, right? Or this may be implemented as local patch for 
GCC?


BTW, I actually saw UNKNOWN_LOCATION for this expr:

volatile double var;  // this is tcc_decaration, so we have 
UNKNOWN_LOCATION for it.


I wonder if we need emit __ubsan_handle_float_cast_overflow here at all.


Re: [PATCH 7/7] Libsanitizer merge from upstream r249633.

2015-10-14 Thread Maxim Ostapenko

On 14/10/15 14:06, Jakub Jelinek wrote:

On Wed, Oct 14, 2015 at 01:51:44PM +0300, Maxim Ostapenko wrote:

Ok, got it. The first solution would require changes in libsanitizer because
heuristic doesn't work for GCC, so perhaps new UBSan entry point should go
upstream, right? Or this may be implemented as local patch for GCC?

No.  The heuristics relies on:
1) either it is old style float cast overflow without location
2) or it is new style float cast with location, but the location must:
a) not have NULL filename
b) the filename must not be ""
c) the filename must not be "\1"
So, my proposal was to emit in GCC the old style float cast overflow if a), b) 
or
c) is true, otherwise the new style.  I have no idea what you mean by
heuristic doesn't work for GCC after that.


I mean that there are some cases where (FilenameOrTypeDescriptor[0] + 
FilenameOrTypeDescriptor[1] < 2) is not sufficient to determine if we 
should use old style. I actually caught this on float-cast-overflow-10.c 
testcase. Here:


$ /home/max/build/master-ref/gcc/xgcc -B/home/max/build/master-ref/gcc/ 
/home/max/workspace/downloads/svn/trunk/gcc/testsuite/c-c++-common/ubsan/float-cast-overflow-10.c 
-B/home/max/build/master-ref/x86_64-unknown-linux-gnu/./libsanitizer/ 
-B/home/max/build/master-ref/x86_64-unknown-linux-gnu/./libsanitizer/ubsan/ 
-L/home/max/build/master-ref/x86_64-unknown-linux-gnu/./libsanitizer/ubsan/.libs 
-fno-diagnostics-show-caret -fdiagnostics-color=never -O2 
-fsanitize=float-cast-overflow -fsanitize-recover=float-cast-overflow 
-DUSE_INT128 -DUSE_DFP -DBROKEN_DECIMAL_INT128 -lm -o 
./float-cast-overflow-10.s -S


$ cat float-cast-overflow-10.s

cvt_sc_d32:
.LFB0:
.cfi_startproc
pushq   %rbx
..
.L6:
movl%ebx, %esi
movl$.Lubsan_data0, %edi
call__ubsan_handle_float_cast_overflow
...
.Lubsan_data0:
.quad   .Lubsan_type1
.quad   .Lubsan_type0
.align 2
.type   .Lubsan_type1, @object
.size   .Lubsan_type1, 17
.Lubsan_type1:
.value  -1  // <- TypeKind
.value  32
.string "'_Decimal32'"
.align 2
.type   .Lubsan_type0, @object
.size   .Lubsan_type0, 18
.Lubsan_type0:
.value  0 // <- TypeKind
.value  7
.string "'signed char'"
.section.rodata.cst4,"aM",@progbits,4
.align 4

Here, one can see, we have FilenameOrTypeDescriptor[0]  == -1 and 
FilenameOrTypeDescriptor[1] == 0. So, we end up with wrong decision and 
have SEGV later.

BTW, I actually saw UNKNOWN_LOCATION for this expr:

volatile double var;  // this is tcc_decaration, so we have UNKNOWN_LOCATION
for it.

This is not a complete testcase, so I wonder what exactly you are talking
about.  The above doesn't not generate any
__ubsan_handle_float_cast_overflow calls with
-fsanitize=float-cast-overflow, and
volatile double d;
int bar (void) { return d; }
has location.

Jakub





Re: [PATCH 5/7] Libsanitizer merge from upstream r249633.

2015-10-14 Thread Maxim Ostapenko

On 14/10/15 10:37, Jakub Jelinek wrote:

On Tue, Oct 13, 2015 at 02:20:06PM +0300, Maxim Ostapenko wrote:

This patch removes UBSan stubs from ASan and TSan code. We don't embed UBSan
to ASan and UBSan because that would lead to undefined references to C++
stuff when linking with -static-libasan. AFAIK, sanitizer developers use
different libraries for C and CXX runtimes, but I think this is out of scope
of this merge.

Where is CAN_SANITIZE_UB defined?  I don't see it anywhere in the current
libsanitizer and in the patch only:
grep CAN_SANITIZE_UB libsanitizer-249633-2.diff
+#if CAN_SANITIZE_UB
+# define TSAN_CONTAINS_UBSAN (CAN_SANITIZE_UB && !defined(SANITIZER_GO))
+#if CAN_SANITIZE_UB
+#endif  // CAN_SANITIZE_UB
+#if CAN_SANITIZE_UB
+#endif  // CAN_SANITIZE_UB
+#if CAN_SANITIZE_UB
+#endif  // CAN_SANITIZE_UB
+#if CAN_SANITIZE_UB
+#endif  // CAN_SANITIZE_UB
+#if CAN_SANITIZE_UB
+#endif  // CAN_SANITIZE_UB
+#if CAN_SANITIZE_UB
+#endif  // CAN_SANITIZE_UB
+#if CAN_SANITIZE_UB
+#endif  // CAN_SANITIZE_UB


Hm, this is strange, perhaps the patch was malformed.



So, unless I'm missing something, it would be best to arrange for
-DCAN_SANITIZE_UB=1 to be in CXXFLAGS for ubsan/ source files and
-DCAN_SANITIZE_UB=0 to be in CXXFLAGS for {a,t}san/ source files?


CAN_SANITIZE_UB definition is hardcoded into new ubsan/ubsan_platform.h 
file. To use DCAN_SANITIZE_UB from CXXFLAGS, we still need some changes 
in libsanitizer against upstream:


Index: libsanitizer/ubsan/ubsan_platform.h
===
--- libsanitizer/ubsan/ubsan_platform.h(revision 250295)
+++ libsanitizer/ubsan/ubsan_platform.h(working copy)
@@ -13,6 +13,7 @@
 #ifndef UBSAN_PLATFORM_H
 #define UBSAN_PLATFORM_H

+#ifndef CAN_SANITIZE_UB
 // Other platforms should be easy to add, and probably work as-is.
 #if (defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__)) 
&& \

 (defined(__x86_64__) || defined(__i386__) || defined(__arm__) || \
@@ -23,5 +24,6 @@
 #else
 # define CAN_SANITIZE_UB 0
 #endif
+#endif // CAN_SANITIZE_UB

 #endif


Are there any other defines that are supposedly set from cmake or wherever
upstream and are left undefined?


There is ASAN_DYNAMIC macro, but I see it into current libsanitizer too 
and it's not touched in any Makefile. Same for 
ASAN_DYNAMIC_RUNTIME_THUNK, that is used for Windows build and 
ASAN_LOW_MEMORY, that set explicitly only for Android. Do we need to 
touch them?
Also, ASAN_FLEXIBLE_MAPPING_AND_OFFSET was bumped upstream, so we don't 
need it anymore.


I'm applying the patch mentioned above, redefining CAN_SANITIZE_UB in 
corresponding Makefiles, dropping ASAN_FLEXIBLE_MAPPING_AND_OFFSET and 
resending libsanitizer-249633-2.diff in corresponding thread.

2015-10-13  Maxim Ostapenko  

* tsan/tsan_defs.h: Define TSAN_CONTAINS_UBSAN to 0.
* asan/asan_flags.cc (InitializeFlags): Do not initialize UBSan flags.
* asan/asan_rtl.cc (AsanInitInternal): Do not init UBSan.

Jakub





Re: [PATCH 2/7] Libsanitizer merge from upstream r249633.

2015-10-15 Thread Maxim Ostapenko

On 14/10/15 10:30, Jakub Jelinek wrote:

On Tue, Oct 13, 2015 at 02:16:23PM +0300, Maxim Ostapenko wrote:

This patch introduces required compiler changes. Now, we don't version
asan_init, we have a special __asan_version_mismatch_check_v[n] symbol for
this.

For this, I just have to wonder what is the actual improvement over what we
had.  To me it looks like a step in the wrong direction, it will only bloat
the size of the ctors.  I can live with it, but just want to put on record I
think it is a mistake.


Also, asan_stack_malloc_[n] doesn't take a local stack as a second parameter
anymore, so don't pass it.

I think this is another mistake, but this time with actually bad fix on the
compiler side for it.  If I read the code well, previously
__asan_stack_malloc_n would return you the local stack if it failed for
whatever reason, which is actually what you want as fallback.
But, the new code returns NULL instead, so I think you would need to compare
the return value of __asan_stack_malloc_n with NULL and if it is NULL, use
the addr instead of what it returned; which is not what your asan.c change
does.  Now, what is the improvement here?  Bloat the compiler generated
code... :(



Ah, right, fixing this now. Does this looks better now?


2015-10-12  Maxim Ostapenko  

config/

* bootstrap-asan.mk: Replace ASAN_OPTIONS=detect_leaks with
LSAN_OPTIONS=detect_leaks

Missing . at the end, and the config/ hunk missing from the patch.


gcc/

* asan.c (asan_emit_stack_protection): Don't pass local stack to
asan_stack_malloc_[n] anymore.
(asan_finish_file): Instert __asan_version_mismatch_check_v[n] call.

s/Instert/Instead/


Fixed now.



Jakub



2015-10-12  Maxim Ostapenko  

config/

	* bootstrap-asan.mk: Replace ASAN_OPTIONS=detect_leaks with
	LSAN_OPTIONS=detect_leaks.

gcc/

	* asan.c (asan_emit_stack_protection): Don't pass local stack to
	asan_stack_malloc_[n] anymore. Check if asan_stack_malloc_[n] returned
	NULL and use local stack than.
	(asan_finish_file): Insert __asan_version_mismatch_check_v[n] call
	in addition to __asan_init.
	* sanitizer.def (BUILT_IN_ASAN_INIT): Rename to __asan_init.
	(BUILT_IN_ASAN_VERSION_MISMATCH_CHECK): Add new builtin call.

gcc/testsuite/

	g++.dg/asan/default-options-1.C: Adjust testcase.

Index: gcc/asan.c
===
--- gcc/asan.c	(revision 228817)
+++ gcc/asan.c	(working copy)
@@ -1132,12 +1132,16 @@
   snprintf (buf, sizeof buf, "__asan_stack_malloc_%d",
 		use_after_return_class);
   ret = init_one_libfunc (buf);
-  rtx addr = convert_memory_address (ptr_mode, base);
-  ret = emit_library_call_value (ret, NULL_RTX, LCT_NORMAL, ptr_mode, 2,
+  ret = emit_library_call_value (ret, NULL_RTX, LCT_NORMAL, ptr_mode, 1,
  GEN_INT (asan_frame_size
 	  + base_align_bias),
- TYPE_MODE (pointer_sized_int_node),
- addr, ptr_mode);
+ TYPE_MODE (pointer_sized_int_node));
+  /* __asan_stack_malloc_[n] returns a pointer to fake stack if succeeded
+	 and NULL otherwise.  Check if RET value is NULL and jump over the
+	 BASE reassignment in this case.  Otherwise, reassign BASE to RET.  */
+  int very_unlikely = REG_BR_PROB_BASE / 2000 - 1;
+  emit_cmp_and_jump_insns (ret, const0_rtx, EQ, NULL_RTX,
+			   VOIDmode, 0, lab, very_unlikely);
   ret = convert_memory_address (Pmode, ret);
   emit_move_insn (base, ret);
   emit_label (lab);
@@ -2470,6 +2474,8 @@
 {
   tree fn = builtin_decl_implicit (BUILT_IN_ASAN_INIT);
   append_to_statement_list (build_call_expr (fn, 0), &asan_ctor_statements);
+  fn = builtin_decl_implicit (BUILT_IN_ASAN_VERSION_MISMATCH_CHECK);
+  append_to_statement_list (build_call_expr (fn, 0), &asan_ctor_statements);
 }
   FOR_EACH_DEFINED_VARIABLE (vnode)
 if (TREE_ASM_WRITTEN (vnode->decl)
Index: gcc/sanitizer.def
===
--- gcc/sanitizer.def	(revision 228817)
+++ gcc/sanitizer.def	(working copy)
@@ -27,8 +27,11 @@
for other FEs by asan.c.  */
 
 /* Address Sanitizer */
-DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_INIT, "__asan_init_v4",
+DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_INIT, "__asan_init",
 		  BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST)
+DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_VERSION_MISMATCH_CHECK,
+		  "__asan_version_mismatch_check_v6",
+		  BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST)
 /* Do not reorder the BUILT_IN_ASAN_{REPORT,CHECK}* builtins, e.g. cfgcleanup.c
relies on this order.  */
 DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_REPORT_LOAD1, "__asan_report_load1",
Index: gcc/testsuite/g++.dg/asan/default-options-1.C
===
--- gcc/testsuite/g++.dg/asan/default-options-1.C	(revision 228817)
+++ gcc/testsuite/g++.dg/asan/default-options-1.C	

Re: [PATCH 7/7] Libsanitizer merge from upstream r249633.

2015-10-16 Thread Maxim Ostapenko

On 14/10/15 15:12, Jakub Jelinek wrote:

On Wed, Oct 14, 2015 at 03:02:22PM +0300, Maxim Ostapenko wrote:

On 14/10/15 14:06, Jakub Jelinek wrote:

On Wed, Oct 14, 2015 at 01:51:44PM +0300, Maxim Ostapenko wrote:

Ok, got it. The first solution would require changes in libsanitizer because
heuristic doesn't work for GCC, so perhaps new UBSan entry point should go
upstream, right? Or this may be implemented as local patch for GCC?

No.  The heuristics relies on:
1) either it is old style float cast overflow without location
2) or it is new style float cast with location, but the location must:
a) not have NULL filename
b) the filename must not be ""
c) the filename must not be "\1"
So, my proposal was to emit in GCC the old style float cast overflow if a), b) 
or
c) is true, otherwise the new style.  I have no idea what you mean by
heuristic doesn't work for GCC after that.

I mean that there are some cases where (FilenameOrTypeDescriptor[0] +
FilenameOrTypeDescriptor[1] < 2) is not sufficient to determine if we should
use old style. I actually caught this on float-cast-overflow-10.c testcase.

Ah, ok, in that case the heuristics is flawed.  If they want to keep it,
they should check if MaybeFromTypeKind is either < 2 or equal to 0x1fe.
Can you report it upstream?  If that is changed, we'd need to change the
above and also add
   d) the filename must not start with "\xff\xff"
to the rules.

I think it would be better to just add a whole new entrypoint, but if they
think the heuristics is good enough, they should at least fix it up.

Jakub



Done. I've realized that we could just set loc to input_location if loc 
== UNKNOWN_LOCATION. In this case, we always would have new style. This 
would require some changes in tests, because upstream UBSan suppress 
different reports for one location. How about this?


-Maxim
gcc/ChangeLog:

2015-10-16  Maxim Ostapenko  

	* ubsan.c (ubsan_instrument_float_cast): If location is unknown, assign
	 input_location to loc. Propagate loc to ubsan_create_data.

gcc/testsuite/ChangeLog:

2015-10-16  Maxim Ostapenko  

	* c-c++-common/ubsan/float-cast-overflow-10.c: Adjust test.
	* c-c++-common/ubsan/float-cast-overflow-8.c: Likewise.
	* c-c++-common/ubsan/float-cast-overflow-9.c: Likewise.

Index: gcc/ubsan.c
===
--- gcc/ubsan.c	(revision 228817)
+++ gcc/ubsan.c	(working copy)
@@ -1484,6 +1484,7 @@
   machine_mode mode = TYPE_MODE (expr_type);
   int prec = TYPE_PRECISION (type);
   bool uns_p = TYPE_UNSIGNED (type);
+  if (loc == UNKNOWN_LOCATION) loc = input_location;
 
   /* Float to integer conversion first truncates toward zero, so
  even signed char c = 127.875f; is not problematic.
@@ -1581,8 +1582,8 @@
   else
 {
   /* Create the __ubsan_handle_float_cast_overflow fn call.  */
-  tree data = ubsan_create_data ("__ubsan_float_cast_overflow_data", 0,
- NULL, ubsan_type_descriptor (expr_type),
+  tree data = ubsan_create_data ("__ubsan_float_cast_overflow_data", 1,
+ &loc, ubsan_type_descriptor (expr_type),
  ubsan_type_descriptor (type), NULL_TREE,
  NULL_TREE);
   enum built_in_function bcode
Index: gcc/testsuite/c-c++-common/ubsan/float-cast-overflow-10.c
===
--- gcc/testsuite/c-c++-common/ubsan/float-cast-overflow-10.c	(revision 228817)
+++ gcc/testsuite/c-c++-common/ubsan/float-cast-overflow-10.c	(working copy)
@@ -10,70 +10,37 @@
 
 /* _Decimal32 */
 /* { dg-output "value  is outside the range of representable values of type 'signed char'\[^\n\r]*(\n|\r\n|\r)" } */
-/* { dg-output "\[^\n\r]*value  is outside the range of representable values of type 'signed char'\[^\n\r]*(\n|\r\n|\r)" } */
 /* { dg-output "\[^\n\r]*value  is outside the range of representable values of type 'char'\[^\n\r]*(\n|\r\n|\r)" } */
-/* { dg-output "\[^\n\r]*value  is outside the range of representable values of type 'char'\[^\n\r]*(\n|\r\n|\r)" } */
 /* { dg-output "\[^\n\r]*value  is outside the range of representable values of type 'unsigned char'\[^\n\r]*(\n|\r\n|\r)" } */
-/* { dg-output "\[^\n\r]*value  is outside the range of representable values of type 'unsigned char'\[^\n\r]*(\n|\r\n|\r)" } */
 /* { dg-output "\[^\n\r]*value  is outside the range of representable values of type 'short int'\[^\n\r]*(\n|\r\n|\r)" } */
-/* { dg-output "\[^\n\r]*value  is outside the range of representable values of type 'short int'\[^\n\r]*(\n|\r\n|\r)" } */
 /* { dg-output "\[^\n\r]*value  is outside the range of representable values of type 'short unsigned int'\[^\n\r]*(\n|\r\n|\r)" } */
-/* { dg-output "\[^\n\r]*value  is outside 

Re: [PATCH 1/7] Libsanitizer merge from upstream r249633.

2015-10-16 Thread Maxim Ostapenko

On 16/10/15 16:48, Renato Golin wrote:

On 14 October 2015 at 19:38, Renato Golin  wrote:

On 14 October 2015 at 19:21, Evgenii Stepanov  wrote:

Wait. As Jakub correctly pointed out in the other thread, there is no
obvious reason why there could not be a single shadow offset value
that would work for all 3 possible VMA settings. I suggest figuring
this out first.

We are.

For anyone interested, here are the first few reviews:

http://reviews.llvm.org/D13781
http://reviews.llvm.org/D13782

There's more coming... :)

I don't want to spam this list for all the future patches, so if
you're interested, you might monitor the LLVM list, or register in our
Phabricator and create a filter for reviews with "VMA" to always CC
you.

cheers,
--renato



Yeah, thanks. Just wondering if I should step back until they are 
resolved upstream or we can have another merge in the future (stage3 is 
coming ...)?


-Maxim


[PATCH v2 0/6] Libsanitizer merge from upstream r250806 (was r249633).

2015-10-20 Thread Maxim Ostapenko

Hi,

this is the second attempt to perform libsanitizer merge from upstream. 
In previous patch set ( 
https://gcc.gnu.org/ml/gcc-patches/2015-10/msg01212.html) we have 
revealed an issue with heuristic for old/new style ubsan_data that was 
needed to be fixed upstream + some errors in compiler changes were 
found. I thought that it would me too messy to proceed review in the 
previous thread, so creating the new one.


The first patch is the merge itself. Since the heuristic fix for old/new 
style ubsan_data selection was applied upstream, I'm bumping revision to 
r250806.
Since there aren't significant changes from r249633, I think this should 
be fine.


The second one combines all compiler-related changes and addresses 
Jakub's nits from previous review.


Patches 3, 4 and 5 are applied to library and were preapproved in 
previous review, but I'm attaching them here to form the full patch set.


In patch 6, I'm trying to add a brief instruction how to perform the 
merge. This is just a documentation patch.


Tested and {A, UB}San bootstrapped on x86-linux-gnu, x86_64-linux-gnu 
and aarch64-linux-gnu targets.


Thanks,
-Maxim


[PATCH v2 2/6] Libsanitizer merge from upstream r250806 (was r249633).

2015-10-20 Thread Maxim Ostapenko
This patch introduces required compiler changes. Now, we don't version 
asan_init, we have a special __asan_version_mismatch_check_v[n] symbol 
for this. asan_stack_malloc_[n] doesn't take a local stack as a second 
parameter anymore, so don't pass it. Also, ubsan_instrument_float_cast 
was adjusted to pass source location for libubsan if it is possible.
gcc/ChangeLog:

2015-10-20  Maxim Ostapenko  

gcc/

	* asan.c (asan_emit_stack_protection): Don't pass local stack to
	asan_stack_malloc_[n] anymore. Check if asan_stack_malloc_[n] returned
	NULL and use local stack than.
	(asan_finish_file): Insert __asan_version_mismatch_check_v[n] call
	in addition to __asan_init.
	* sanitizer.def (BUILT_IN_ASAN_INIT): Rename to __asan_init.
	(BUILT_IN_ASAN_VERSION_MISMATCH_CHECK): Add new builtin call.
	* asan.h (asan_intercepted_p): Handle new string builtins.
	* ubsan.c (ubsan_use_new_style_p): New function.
	(ubsan_instrument_float_cast): If location is unknown, assign
	input_location to loc. Propagate loc to ubsan_create_data if
	ubsan_use_new_style_p returned true.

config/

	* bootstrap-asan.mk: Replace ASAN_OPTIONS=detect_leaks with
	LSAN_OPTIONS=detect_leaks.

gcc/testsuite/ChangeLog:

2015-10-20  Maxim Ostapenko  

	* c-c++-common/ubsan/float-cast-overflow-10.c: Adjust test.
	* c-c++-common/ubsan/float-cast-overflow-8.c: Likewise.
	* c-c++-common/ubsan/float-cast-overflow-9.c: Likewise.
	* g++.dg/asan/default-options-1.C: Likewise.

Index: gcc/asan.c
===
--- gcc/asan.c	(revision 228817)
+++ gcc/asan.c	(working copy)
@@ -1132,12 +1132,16 @@
   snprintf (buf, sizeof buf, "__asan_stack_malloc_%d",
 		use_after_return_class);
   ret = init_one_libfunc (buf);
-  rtx addr = convert_memory_address (ptr_mode, base);
-  ret = emit_library_call_value (ret, NULL_RTX, LCT_NORMAL, ptr_mode, 2,
+  ret = emit_library_call_value (ret, NULL_RTX, LCT_NORMAL, ptr_mode, 1,
  GEN_INT (asan_frame_size
 	  + base_align_bias),
- TYPE_MODE (pointer_sized_int_node),
- addr, ptr_mode);
+ TYPE_MODE (pointer_sized_int_node));
+  /* __asan_stack_malloc_[n] returns a pointer to fake stack if succeeded
+	 and NULL otherwise.  Check RET value is NULL here and jump over the
+	 BASE reassignment in this case.  Otherwise, reassign BASE to RET.  */
+  int very_unlikely = REG_BR_PROB_BASE / 2000 - 1;
+  emit_cmp_and_jump_insns (ret, const0_rtx, EQ, NULL_RTX,
+			   VOIDmode, 0, lab, very_unlikely);
   ret = convert_memory_address (Pmode, ret);
   emit_move_insn (base, ret);
   emit_label (lab);
@@ -2470,6 +2474,8 @@
 {
   tree fn = builtin_decl_implicit (BUILT_IN_ASAN_INIT);
   append_to_statement_list (build_call_expr (fn, 0), &asan_ctor_statements);
+  fn = builtin_decl_implicit (BUILT_IN_ASAN_VERSION_MISMATCH_CHECK);
+  append_to_statement_list (build_call_expr (fn, 0), &asan_ctor_statements);
 }
   FOR_EACH_DEFINED_VARIABLE (vnode)
 if (TREE_ASM_WRITTEN (vnode->decl)
Index: gcc/sanitizer.def
===
--- gcc/sanitizer.def	(revision 228817)
+++ gcc/sanitizer.def	(working copy)
@@ -27,8 +27,11 @@
for other FEs by asan.c.  */
 
 /* Address Sanitizer */
-DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_INIT, "__asan_init_v4",
+DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_INIT, "__asan_init",
 		  BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST)
+DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_VERSION_MISMATCH_CHECK,
+		  "__asan_version_mismatch_check_v6",
+		  BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST)
 /* Do not reorder the BUILT_IN_ASAN_{REPORT,CHECK}* builtins, e.g. cfgcleanup.c
relies on this order.  */
 DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_REPORT_LOAD1, "__asan_report_load1",
Index: gcc/testsuite/c-c++-common/ubsan/float-cast-overflow-10.c
===
--- gcc/testsuite/c-c++-common/ubsan/float-cast-overflow-10.c	(revision 228817)
+++ gcc/testsuite/c-c++-common/ubsan/float-cast-overflow-10.c	(working copy)
@@ -10,70 +10,37 @@
 
 /* _Decimal32 */
 /* { dg-output "value  is outside the range of representable values of type 'signed char'\[^\n\r]*(\n|\r\n|\r)" } */
-/* { dg-output "\[^\n\r]*value  is outside the range of representable values of type 'signed char'\[^\n\r]*(\n|\r\n|\r)" } */
 /* { dg-output "\[^\n\r]*value  is outside the range of representable values of type 'char'\[^\n\r]*(\n|\r\n|\r)" } */
-/* { dg-output "\[^\n\r]*value  is outside the range of representable values of type 'char'\[^\n\r]*(\n|\r\n|\r)" } */
 /* { dg-output "\[^\n\r]*value  is outside the range of representable values of type 'unsigned char'\[^\n\r]*(\n|\r\n|\r)" } */
-/* { dg-output "\[^\n\r]*value  is outside the range o

Re: [PATCH v2 0/6] Libsanitizer merge from upstream r250806 (was r249633).

2015-10-20 Thread Maxim Ostapenko
This is just reapplied patch for SPARC by David S. Miller. The patch was 
preapproved here: 
(https://gcc.gnu.org/ml/gcc-patches/2015-10/msg01214.html).
2015-10-20  Maxim Ostapenko  

	PR sanitizer/63958
	Reapply:
	2014-10-14  David S. Miller  

	* sanitizer_common/sanitizer_platform_limits_linux.cc (time_t):
	Define at __kernel_time_t, as needed for sparc.
	(struct __old_kernel_stat): Don't check if __sparc__ is defined.
	* libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h
	(__sanitizer): Define struct___old_kernel_stat_sz,
	struct_kernel_stat_sz, and struct_kernel_stat64_sz for sparc.
	(__sanitizer_ipc_perm): Adjust for sparc targets.
	(__sanitizer_shmid_ds): Likewsie.
	(__sanitizer_sigaction): Likewise.
	(IOC_SIZE): Likewsie.

Index: libsanitizer/sanitizer_common/sanitizer_platform_limits_linux.cc
===
--- libsanitizer/sanitizer_common/sanitizer_platform_limits_linux.cc	(revision 250059)
+++ libsanitizer/sanitizer_common/sanitizer_platform_limits_linux.cc	(working copy)
@@ -38,6 +38,7 @@
 #define uid_t __kernel_uid_t
 #define gid_t __kernel_gid_t
 #define off_t __kernel_off_t
+#define time_t __kernel_time_t
 // This header seems to contain the definitions of _kernel_ stat* structs.
 #include 
 #undef ino_t
@@ -62,7 +63,7 @@
 }  // namespace __sanitizer
 
 #if !defined(__powerpc64__) && !defined(__x86_64__) && !defined(__aarch64__)\
-&& !defined(__mips__)
+&& !defined(__mips__) && !defined(__sparc__)
 COMPILER_CHECK(struct___old_kernel_stat_sz == sizeof(struct __old_kernel_stat));
 #endif
 
Index: libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h
===
--- libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h	(revision 250059)
+++ libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h	(working copy)
@@ -83,6 +83,14 @@
   const unsigned struct_kernel_stat_sz = 144;
   #endif
   const unsigned struct_kernel_stat64_sz = 104;
+#elif defined(__sparc__) && defined(__arch64__)
+  const unsigned struct___old_kernel_stat_sz = 0;
+  const unsigned struct_kernel_stat_sz = 104;
+  const unsigned struct_kernel_stat64_sz = 144;
+#elif defined(__sparc__) && !defined(__arch64__)
+  const unsigned struct___old_kernel_stat_sz = 0;
+  const unsigned struct_kernel_stat_sz = 64;
+  const unsigned struct_kernel_stat64_sz = 104;
 #endif
   struct __sanitizer_perf_event_attr {
 unsigned type;
@@ -105,7 +113,7 @@
 
 #if defined(__powerpc64__)
   const unsigned struct___old_kernel_stat_sz = 0;
-#else
+#elif !defined(__sparc__)
   const unsigned struct___old_kernel_stat_sz = 32;
 #endif
 
@@ -184,6 +192,18 @@
 unsigned short __pad1;
 unsigned long __unused1;
 unsigned long __unused2;
+#elif defined(__sparc__)
+# if defined(__arch64__)
+unsigned mode;
+unsigned short __pad1;
+# else
+unsigned short __pad1;
+unsigned short mode;
+unsigned short __pad2;
+# endif
+unsigned short __seq;
+unsigned long long __unused1;
+unsigned long long __unused2;
 #else
 unsigned short mode;
 unsigned short __pad1;
@@ -201,6 +221,26 @@
 
   struct __sanitizer_shmid_ds {
 __sanitizer_ipc_perm shm_perm;
+  #if defined(__sparc__)
+  # if !defined(__arch64__)
+u32 __pad1;
+  # endif
+long shm_atime;
+  # if !defined(__arch64__)
+u32 __pad2;
+  # endif
+long shm_dtime;
+  # if !defined(__arch64__)
+u32 __pad3;
+  # endif
+long shm_ctime;
+uptr shm_segsz;
+int shm_cpid;
+int shm_lpid;
+unsigned long shm_nattch;
+unsigned long __glibc_reserved1;
+unsigned long __glibc_reserved2;
+  #else
   #ifndef __powerpc__
 uptr shm_segsz;
   #elif !defined(__powerpc64__)
@@ -238,6 +278,7 @@
 uptr __unused4;
 uptr __unused5;
   #endif
+#endif
   };
 #elif SANITIZER_FREEBSD
   struct __sanitizer_ipc_perm {
@@ -555,9 +596,13 @@
 #else
 __sanitizer_sigset_t sa_mask;
 #ifndef __mips__
+#if defined(__sparc__)
+unsigned long sa_flags;
+#else
 int sa_flags;
 #endif
 #endif
+#endif
 #if SANITIZER_LINUX
 void (*sa_restorer)();
 #endif
@@ -799,7 +844,7 @@
 
 #define IOC_NRBITS 8
 #define IOC_TYPEBITS 8
-#if defined(__powerpc__) || defined(__powerpc64__) || defined(__mips__)
+#if defined(__powerpc__) || defined(__powerpc64__) || defined(__mips__) || defined(__sparc__)
 #define IOC_SIZEBITS 13
 #define IOC_DIRBITS 3
 #define IOC_NONE 1U
@@ -829,7 +874,17 @@
 #define IOC_DIR(nr) (((nr) >> IOC_DIRSHIFT) & IOC_DIRMASK)
 #define IOC_TYPE(nr) (((nr) >> IOC_TYPESHIFT) & IOC_TYPEMASK)
 #define IOC_NR(nr) (((nr) >> IOC_NRSHIFT) & IOC_NRMASK)
+
+#if defined(__sparc__)
+// In sparc the 14 bits SIZE field overlaps with the
+// least significant bit of DIR, so either IOC_READ or
+// IOC_WRITE shall be 1 in order to get a non-zero SIZE

[PATCH v2 4/6] Libsanitizer merge from upstream r250806 (was r249633).

2015-10-20 Thread Maxim Ostapenko
This is a reapplied Jakub's patch for disabling ODR violation detection. 
The patch was preapproved here: 
(https://gcc.gnu.org/ml/gcc-patches/2015-10/msg01215.html).
2015-10-20  Maxim Ostapenko  

	PR bootstrap/63888
	Reapply:
	2015-02-20  Jakub Jelinek  

	* asan/asan_globals.cc (RegisterGlobal): Disable detect_odr_violation
	support until it is rewritten upstream.

	* c-c++-common/asan/pr63888.c: New test.

Index: libsanitizer/asan/asan_globals.cc
===
--- libsanitizer/asan/asan_globals.cc	(revision 250059)
+++ libsanitizer/asan/asan_globals.cc	(working copy)
@@ -146,7 +146,9 @@
   CHECK(AddrIsInMem(g->beg));
   CHECK(AddrIsAlignedByGranularity(g->beg));
   CHECK(AddrIsAlignedByGranularity(g->size_with_redzone));
-  if (flags()->detect_odr_violation) {
+  // This "ODR violation" detection is fundamentally incompatible with
+  // how GCC registers globals.  Disable as useless until rewritten upstream.
+  if (0 && flags()->detect_odr_violation) {
 // Try detecting ODR (One Definition Rule) violation, i.e. the situation
 // where two globals with the same name are defined in different modules.
 if (__asan_region_is_poisoned(g->beg, g->size_with_redzone)) {


[PATCH v2 5/6] Libsanitizer merge from upstream r250806 (was r249633).

2015-10-20 Thread Maxim Ostapenko
This patch adjusts the fix for 
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61771 to extract the last 
PC from the stack frame if no valid FP is available for ARM. The patch 
was preapproved here: 
(https://gcc.gnu.org/ml/gcc-patches/2015-10/msg01217.html).
2015-10-20  Maxim Ostapenko  

	* sanitizer_common/sanitizer_stacktrace.cc (GetCanonicFrame): Assume we
	compiled code with GCC when extracting the caller PC for ARM if no
	valid frame pointer is available.

Index: libsanitizer/sanitizer_common/sanitizer_stacktrace.cc
===
--- libsanitizer/sanitizer_common/sanitizer_stacktrace.cc	(revision 250059)
+++ libsanitizer/sanitizer_common/sanitizer_stacktrace.cc	(working copy)
@@ -62,8 +62,8 @@
   // Nope, this does not look right either. This means the frame after next does
   // not have a valid frame pointer, but we can still extract the caller PC.
   // Unfortunately, there is no way to decide between GCC and LLVM frame
-  // layouts. Assume LLVM.
-  return bp_prev;
+  // layouts. Assume GCC.
+  return bp_prev - 1;
 #else
   return (uhwptr*)bp;
 #endif


[PATCH v2 6/6] Libsanitizer merge from upstream r250806 (was r249633).

2015-10-20 Thread Maxim Ostapenko
In this patch, I'm trying to add a general instruction how to perform 
the merge. This is just a documentation patch, any suggestions and 
opinions are welcome.
Index: libsanitizer/HOWTO_MERGE
===
--- libsanitizer/HOWTO_MERGE	(revision 0)
+++ libsanitizer/HOWTO_MERGE	(working copy)
@@ -0,0 +1,26 @@
+In general, merging process should not be very difficult, but we need to
+track various ABI changes and GCC-specific patches carefully.  Here is a
+general list of actions required to perform the merge:
+
+- Checkout recent GCC tree.
+- Run merge.sh script from libsanitizer directory.
+- Modify Makefile.am files into asan/tsan/lsan/ubsan/sanitizer_common/interception
+  directories if needed.  In particular, you may need to add new source files
+  and remove old ones in source files list, add new flags to {C, CXX}FLAGS if
+  needed and update DEFS with new defined variables.
+- Apply all needed GCC-specific patches to libsanitizer (note that some of
+  them might be already included to upstream).
+- Apply all necessary compiler changes.  Be especially careful here, you must
+  not break ABI between compiler and library.
+- Modify configure.ac file if needed (e.g. if you need to add link against new
+  library for sanitizer lilbs).
+- Remove unused (deleted by merge) files from all source and include
+  directories.  Be especially careful with headers, because they aren't listed
+  in Makefiles explicitly.
+- Regenerate configure script and all Makefiles by autoreconf.  You should use
+  exactly the same autotools version as for other GCC directories (current
+  version is 2.64, https://www.gnu.org/software/automake/faq/autotools-faq.html
+  for details how to install/use it).
+- Run regression testing on at least three platforms (e.g. x86-linux-gnu,
+  x86_64-linux-gnu, aarch64-linux-gnu).
+- Run {A, UB}San bootstrap on at least three platforms.


Re: [PATCH v2 1/6] Libsanitizer merge from upstream r250806 (was r249633).

2015-10-20 Thread Maxim Ostapenko
Great, thanks! I'm going to commit the whole patch set tomorrow morning 
if no objections.


On 20/10/15 14:52, Jakub Jelinek wrote:

On Tue, Oct 20, 2015 at 02:18:25PM +0300, Maxim Ostapenko wrote:

This is the merge itself. Added DCAN_SANITIZE_UB={0, 1} and nuked
DASAN_FLEXIBLE_MAPPING_AND_OFFSET=0 (not used now) in corresponding
Makefiles.

Ok.

Jakub





[PATCH] Fix bootsrap/68041

2015-10-21 Thread Maxim Ostapenko

Hi,

recent libsanitizer merge ( 
https://gcc.gnu.org/ml/gcc-patches/2015-10/msg01851.html) broke 
bootstrap on x86_64-apple-darwin14 because for Darwin sanitizer libs 
shouldn't be linked with -lrt flag. Also, right now, libubsan links with 
-lc++abi for Darwin, that is wrong, because we don't want to link 
against system clang++'s C++ library (Dominique, am I right here?). This 
patch fixes bootstrap by adding additional check to determine if we 
really need librt for sanitizer_common into configure script and removes 
-lc++abi flag for UBSan on Darwin.


Tested on x86_64-linux-gnu, how does it look?

-Maxim
libsanitizer/ChangeLog:

2015-10-21  Maxim Ostapenko  

	PR bootstrap/68041

	* configure.ac (link_sanitizer_common): Link against librt only if it
	contains shm_open, required by sanitizers.
	(CXX_ABI_NEEDED): Remove variable.
	* configure: Regenerate.
	* ubsan/Makefile.am (libubsan_la_LIBADD): Do not add -lc++abi anymore.
	* ubsan/Makefile.in: Regenerate.

Index: libsanitizer/configure
===
--- libsanitizer/configure	(revision 229119)
+++ libsanitizer/configure	(working copy)
@@ -616,8 +616,6 @@
 FORMAT_FILE
 SANITIZER_SUPPORTED_FALSE
 SANITIZER_SUPPORTED_TRUE
-USE_CXX_ABI_FLAG_FALSE
-USE_CXX_ABI_FLAG_TRUE
 USING_MAC_INTERPOSE_FALSE
 USING_MAC_INTERPOSE_TRUE
 link_liblsan
@@ -12029,7 +12027,7 @@
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 12032 "configure"
+#line 12030 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -12135,7 +12133,7 @@
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 12138 "configure"
+#line 12136 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -15516,8 +15514,52 @@
 
 
 # Common libraries that we need to link against for all sanitizer libs.
-link_sanitizer_common='-lrt -lpthread -ldl -lm'
+link_sanitizer_common='-lpthread -ldl -lm'
 
+# At least for glibc, shm_open is in librt.  But don't pull that
+# in if it still doesn't give us the function we want.  This
+# test is copied from libgomp.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for shm_open in -lrt" >&5
+$as_echo_n "checking for shm_open in -lrt... " >&6; }
+if test "${ac_cv_lib_rt_shm_open+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lrt  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char shm_open ();
+int
+main ()
+{
+return shm_open ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_rt_shm_open=yes
+else
+  ac_cv_lib_rt_shm_open=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rt_shm_open" >&5
+$as_echo "$ac_cv_lib_rt_shm_open" >&6; }
+if test "x$ac_cv_lib_rt_shm_open" = x""yes; then :
+  link_sanitizer_common="-lrt $link_sanitizer_common"
+fi
+
+
 # Set up the set of additional libraries that we need to link against for libasan.
 link_libasan=$link_sanitizer_common
 
@@ -15534,9 +15576,57 @@
 link_liblsan=$link_sanitizer_common
 
 
+
+# At least for glibc, clock_gettime is in librt.  But don't pull that
+# in if it still doesn't give us the function we want.  This
+# test is copied from libgomp.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for clock_gettime in -lrt" >&5
+$as_echo_n "checking for clock_gettime in -lrt... " >&6; }
+if test "${ac_cv_lib_rt_clock_gettime+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lrt  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char clock_gettime ();
+int
+main ()
+{
+return clock_gettime ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_rt_clock_gettime=yes
+else
+  ac_cv_lib_rt_clock_gettime=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_

[PATCH] Fix sanitizer/68042

2015-10-22 Thread Maxim Ostapenko

Hi,

currently we have memcmp-1.c and sanity-check-pure-c-1.c (ASan 
testsuite) output pattern test failures on x86_64-apple-darwin14. This 
patch adjusts their expecting patterns to match real ones.


Tested by me on x86_64-unknown-linux-gnu and by Dominique on 
x86_64-apple-darwin14.


Ok to apply?

-Maxim
gcc/testsuite/ChangeLog:

2015-10-22  Maxim Ostapenko  

	PR sanitizer/68042
	* c-c++-common/asan/memcmp-1.c: Adjust test to pass on Darwin.
	* c-c++-common/asan/sanity-check-pure-c-1.c: Likewise.

Index: gcc/testsuite/c-c++-common/asan/memcmp-1.c
===
--- gcc/testsuite/c-c++-common/asan/memcmp-1.c	(revision 229169)
+++ gcc/testsuite/c-c++-common/asan/memcmp-1.c	(working copy)
@@ -16,5 +16,5 @@
 }
 
 /* { dg-output "ERROR: AddressSanitizer: stack-buffer-overflow.*(\n|\r\n|\r)" } */
-/* { dg-output "#0 0x\[0-9a-f\]+ +(in _*(interceptor_|wrap_|)memcmp |\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "#0 0x\[0-9a-f\]+ +(in _*(interceptor_|wrap_|)memcmp|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
 /* { dg-output "#1 0x\[0-9a-f\]+ +(in _*main|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
Index: gcc/testsuite/c-c++-common/asan/sanity-check-pure-c-1.c
===
--- gcc/testsuite/c-c++-common/asan/sanity-check-pure-c-1.c	(revision 229169)
+++ gcc/testsuite/c-c++-common/asan/sanity-check-pure-c-1.c	(working copy)
@@ -10,7 +10,7 @@
 }
 
 /* { dg-output "heap-use-after-free.*(\n|\r\n|\r)" } */
-/* { dg-output "#0 \[^\n\r]*(in _*(interceptor_|)free|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "#0 \[^\n\r]*(in _*(interceptor_|wrap_)free|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
 /* { dg-output "#1 \[^\n\r]*(in _*main (\[^\n\r]*sanity-check-pure-c-1.c:8|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } */
-/* { dg-output "#0 \[^\n\r]*(in _*(interceptor_|)malloc|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "#0 \[^\n\r]*(in _*(interceptor_|wrap_)malloc|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
 /* { dg-output "#1 \[^\n\r]*(in _*main (\[^\n\r]*sanity-check-pure-c-1.c:7|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */


[Committed, PATCH] Update HOWTO_MERGE file for libsanitizer.

2015-10-23 Thread Maxim Ostapenko
This patch updates libsanitizer/HOWTO_MERGE file according to Yura's 
nits here: https://gcc.gnu.org/ml/gcc-patches/2015-10/msg02039.html.


Just a documentation patch, no changes in functionality.

-Maxim
Index: libsanitizer/HOWTO_MERGE
===
--- libsanitizer/HOWTO_MERGE	(revision 229212)
+++ libsanitizer/HOWTO_MERGE	(working copy)
@@ -2,25 +2,38 @@
 track various ABI changes and GCC-specific patches carefully.  Here is a
 general list of actions required to perform the merge:
 
-- Checkout recent GCC tree.
-- Run merge.sh script from libsanitizer directory.
-- Modify Makefile.am files into asan/tsan/lsan/ubsan/sanitizer_common/interception
+* Checkout recent GCC tree.
+* Run merge.sh script from libsanitizer directory.
+* Modify Makefile.am files into asan/tsan/lsan/ubsan/sanitizer_common/interception
   directories if needed.  In particular, you may need to add new source files
   and remove old ones in source files list, add new flags to {C, CXX}FLAGS if
-  needed and update DEFS with new defined variables.
-- Apply all needed GCC-specific patches to libsanitizer (note that some of
+  needed and update DEFS with new defined variables.  You can find these changes
+  in corresponding CMakeLists.txt and config-ix.cmake files from compiler-rt source
+  directory.
+* Apply all needed GCC-specific patches to libsanitizer (note that some of
   them might be already included to upstream).
-- Apply all necessary compiler changes.  Be especially careful here, you must
-  not break ABI between compiler and library.
-- Modify configure.ac file if needed (e.g. if you need to add link against new
+* Apply all necessary compiler changes.  Be especially careful here, you must
+  not break ABI between compiler and library.  You can reveal these changes by
+  inspecting the history of AddressSanitizer.cpp and ThreadSanitizer.cpp files
+  from LLVM source tree.
+* Update ASan testsuite with corresponding tests from lib/asan/tests directory.
+  Not all tests can be migrated easily, so you don't need them all to be adapted.
+* Modify configure.ac file if needed (e.g. if you need to add link against new
   library for sanitizer lilbs).
-- Remove unused (deleted by merge) files from all source and include
-  directories.  Be especially careful with headers, because they aren't listed
-  in Makefiles explicitly.
-- Regenerate configure script and all Makefiles by autoreconf.  You should use
-  exactly the same autotools version as for other GCC directories (current
-  version is 2.64, https://www.gnu.org/software/automake/faq/autotools-faq.html
-  for details how to install/use it).
-- Run regression testing on at least three platforms (e.g. x86-linux-gnu,
-  x86_64-linux-gnu, aarch64-linux-gnu).
-- Run {A, UB}San bootstrap on at least three platforms.
+* Add new target platforms in configure.tgt script if needed.
+* Bump SONAME for sanitizer libraries in asan/tsan/ubsan libtool-version files
+  if ABI has changed.
+* Regenerate configure script and all Makefiles by autoreconf.  You should use
+  exactly the same autoconf and automake versions as for other GCC directories (current
+  versions are written in Makefile.in and configure files).
+* Run regression testing on at least three platforms (e.g. x86-linux-gnu, x86_64-linux-gnu,
+  aarch64-linux-gnu, arm-linux-gnueabi).
+* Run {A, UB}San bootstrap on at least three platforms.
+* Compare ABI of corresponding libclang_rt-asan and newly build libasan libraries.
+  You can use a pretty good libabigail tool (https://sourceware.org/libabigail/index.html)
+  to perform such a comparision.  Note, that the list of exported symbols may differ,
+  e.g. because libasan currently does not include UBSan runtime.
+* Split your changes into logical parts (e.g. raw merge, compiler changes, GCC-specific changes
+  in libasan, configure/Makefile changes). The review process has O(N^2) complexity, so you
+  would simplify and probably speed up the review process by doing this.
+* Send your patches for review to GCC Patches Mailing List (gcc-patches@gcc.gnu.org).


[RFC, PATCH v2] Disable -fprofile-use related optimizations if corresponding .gcda file not found.

2015-10-27 Thread Maxim Ostapenko

Hi!

As was pointed out in previous thread 
(https://gcc.gnu.org/ml/gcc-patches/2015-10/msg00723.html), sometimes 
PGO-built binaries can actually introduce performance regressions. We 
could identify affected object files and disable PGO for them by simply 
removing corresponding .gcda file.

My previous patch was incomplete and had two major drawbacks:

* It disabled unrelated options (e.g. -frename-registers) and 
PGO-related options, set up by user explicitly, if corresponding .gcda 
file is not found.
* As Markus pointed out, in many cases we actually don't want to disable 
PGO-related options even if .gcda file is missing.


This patch tries to solve these issues in the following way:

* Introduce new -fprofile-use-partial switch.
* If -fprofile-use-partial is ON, try to find corresponding .gcda file 
in the very early stage during compiler invoking (actually, when common 
command line options are parsed). If .gcda file exists, enable 
PGO-related optimizations and emit warning otherwise. I believe this 
should not break existing code.


Regtested and bootstrapped on x86_64-unknown-linux-gnu.

Does the patch look sensible?

Thanks,
-Maxim
gcc/ChangeLog:

2015-10-27  Maxim Ostapenko  

	* common.opt (profile_file_name): New variable.
	(fprofile-use-partial): Likewise.
	(fprofile-use-partial=): Likewise.
	* opts.c: Include gcov-io.h.
	(common_handle_option): Defer enabling PGO-related optimizations until
	we know if corresponding .gcda file exists.
	(maybe_setup_aux_base_name): New function.
	(setup_coverage_filename): Likewise.
	(enable_fdo_optimizations): Move up in source file.
	(finish_options): Call maybe_setup_aux_base_name and setup coverage
	filename. Enable PGO-related optimizations if corresponding .gcda file
	exists if -fprofile-use-partial is used.  If -fprofile-use is used,
	enable PGO-related optimizations without any other conditions.
	* coverage.c (coverage_init): Adjust to use profile_file_name.

diff --git a/gcc/common.opt b/gcc/common.opt
index 12ca0d6..fb04201 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -198,6 +198,9 @@ const char *main_input_basename
 Variable
 int main_input_baselength
 
+Variable
+char *profile_file_name
+
 ; Which options have been printed by --help.
 Variable
 char *help_printed
@@ -1861,6 +1864,14 @@ fprofile-use=
 Common Joined RejectNegative
 Enable common options for performing profile feedback directed optimizations, and set -fprofile-dir=.
 
+fprofile-use-partial
+Common Var(flag_profile_use_partial)
+Enable common options for performing profile feedback directed optimizations.
+
+fprofile-use-partial=
+Common Joined RejectNegative
+Enable common options for performing profile feedback directed optimizations, and set -fprofile-dir=.
+
 fprofile-values
 Common Report Var(flag_profile_values)
 Insert code to profile values of expressions.
diff --git a/gcc/coverage.c b/gcc/coverage.c
index 4e08e5f..461dd48 100644
--- a/gcc/coverage.c
+++ b/gcc/coverage.c
@@ -1184,7 +1184,7 @@ void
 coverage_init (const char *filename)
 {
   int len = strlen (filename);
-  int prefix_len = 0;
+  da_file_name = profile_file_name;
 
   /* Since coverage_init is invoked very early, before the pass
  manager, we need to set up the dumping explicitly. This is
@@ -1193,24 +1193,6 @@ coverage_init (const char *filename)
 g->get_passes ()->get_pass_profile ()->static_pass_number;
   g->get_dumps ()->dump_start (profile_pass_num, NULL);
 
-  if (!profile_data_prefix && !IS_ABSOLUTE_PATH (filename))
-profile_data_prefix = getpwd ();
-
-  if (profile_data_prefix)
-prefix_len = strlen (profile_data_prefix);
-
-  /* Name of da file.  */
-  da_file_name = XNEWVEC (char, len + strlen (GCOV_DATA_SUFFIX)
-			  + prefix_len + 2);
-
-  if (profile_data_prefix)
-{
-  memcpy (da_file_name, profile_data_prefix, prefix_len);
-  da_file_name[prefix_len++] = '/';
-}
-  memcpy (da_file_name + prefix_len, filename, len);
-  strcpy (da_file_name + prefix_len + len, GCOV_DATA_SUFFIX);
-
   bbg_file_stamp = local_tick;
   
   if (flag_auto_profile)
diff --git a/gcc/opts.c b/gcc/opts.c
index 9a3fbb3..2e0cfa4 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -30,6 +30,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "opts-diagnostic.h"
 #include "insn-attr-common.h"
 #include "common/common-target.h"
+#include "gcov-io.h"
 
 static void set_Wstrict_aliasing (struct gcc_options *opts, int onoff);
 
@@ -660,6 +661,97 @@ default_options_optimization (struct gcc_options *opts,
 			 lang_mask, handlers, loc, dc);
 }
 
+/* Enable FDO-related flags.  */
+
+static void
+enable_fdo_optimizations (struct gcc_options *opts,
+			  struct gcc_options *opts_set,
+			  int value)
+{
+  if (!opts_set->x_flag_branch_probabilities)
+opts->x_flag_branch_probabilities = value;
+  if (!opts_set->x_flag_profile_values)
+opts->x_flag_profile_values = value;
+  if (!opts_set->x_f

Re: [PATCH]Add -fprofile-use option for check_effective_target_freorder.

2015-10-27 Thread Maxim Ostapenko

On 27/10/15 14:06, Bernd Schmidt wrote:

On 10/27/2015 11:54 AM, Renlin Li wrote:

Yes. In all of the related testcases, only -freorder-and-partition flag
is provided explicitly.
How about creating a new dg-add-options for freorder?

proc add_options_for_freorder { flags } {
 return "$flags -freorder-blocks-and-partition -fprofile-use"
}


proc check_effective_target_freorder {} {
 return [check_no_compiler_messages freorder object {
 void foo (void) { }
 } [add_options_for_freorder ""]]
}


I don't know that tcl syntax but apparently this is done already for a 
number of other cases. So, probably the right thing to do.


You might want to coordinate with Maxim ostapenko who's currently 
working on another -fprofile-use patch. Hopefully not one that 
disables -freorder-blocks-and-partition if it can't find .gcda files.


AFAU, adding -fprofile-use would lead to enabling a bunch of PGO-related 
optimizations wherever you have .gcda file or not. So, you can end up 
with a completely different optimization pipeline for your tests if you 
enable -fprofile-use for them. Is it desirable?


Anyway, disabling any compile options provided by user explicitly sounds 
like a bad idea for me, so disabling -freorder-blocks-and-partition if 
it can't find .gcda file seems to be not acceptable.


-Maxim



Bernd





[PATCH, ASan] Add new tests for string interceptors.

2015-10-28 Thread Maxim Ostapenko

Hi,

since the last libsanitizer merge happened, we have new string 
interceptors in libasan: strstr, strcasestr, strspn, strcspn and 
strpbrk. This patch migrates corresponding tests for them from LLVM. 
Also, asan_intercepted_p predicate is updated to handle corresponding 
builtin codes.


Regtested and bootstrapped on x86_64-unknown-linux-gnu, OK to apply?

-Maxim
gcc/ChangeLog:

2015-10-28  Maxim Ostapenko  

	* asan.h (asan_intercepted_p): Handle BUILT_IN_STRCSPN,
	BUILT_IN_STRPBRK, BUILT_IN_STRSPN and BUILT_IN_STRSTR.

gcc/testsuite/ChangeLog:

2015-10-28  Maxim Ostapenko  

	* c-c++-common/asan/strcasestr-1.c: New test.
	* c-c++-common/asan/strcasestr-2.c: Likewise.
	* c-c++-common/asan/strcspn-1.c: Likewise.
	* c-c++-common/asan/strcspn-2.c: Likewise.
	* c-c++-common/asan/strpbrk-1.c: Likewise.
	* c-c++-common/asan/strpbrk-2.c: Likewise.
	* c-c++-common/asan/strspn-1.c: Likewise.
	* c-c++-common/asan/strspn-2.c: Likewise.
	* c-c++-common/asan/strstr-1.c: Likewise.
	* c-c++-common/asan/strstr-2.c: Likewise.

Index: gcc/asan.h
===
--- gcc/asan.h	(revision 229169)
+++ gcc/asan.h	(working copy)
@@ -103,6 +103,10 @@
 	 || fcode == BUILT_IN_STRNCASECMP
 	 || fcode == BUILT_IN_STRNCAT
 	 || fcode == BUILT_IN_STRNCMP
+	 || fcode == BUILT_IN_STRCSPN
+	 || fcode == BUILT_IN_STRPBRK
+	 || fcode == BUILT_IN_STRSPN
+	 || fcode == BUILT_IN_STRSTR
 	 || fcode == BUILT_IN_STRNCPY;
 }
 #endif /* TREE_ASAN */
Index: gcc/testsuite/c-c++-common/asan/strcasestr-1.c
===
--- gcc/testsuite/c-c++-common/asan/strcasestr-1.c	(revision 0)
+++ gcc/testsuite/c-c++-common/asan/strcasestr-1.c	(working copy)
@@ -0,0 +1,29 @@
+/* { dg-do run } */
+/* { dg-set-target-env-var ASAN_OPTIONS "strict_string_checks=true" } */
+/* { dg-shouldfail "asan" } */
+
+#include 
+#include 
+
+#ifndef __cplusplus
+#define _GNU_SOURCE
+#else
+extern "C"
+#endif
+char *
+strcasestr(const char *haystack, const char *needle);
+
+int main(int argc, char **argv) {
+  char *r = 0;
+  char s2[] = "c";
+  char s1[4] = "abC";
+  __asan_poison_memory_region ((char *)&s1[2], 2);
+  r = strcasestr(s1, s2);
+  assert(r == s1 + 2);
+  return 0;
+}
+
+/* { dg-output "READ of size 4 at .* thread T0.*" } */
+/* { dg-output ".*(main)?.*strcasestr-1.(c:21)?.*" } */
+/* { dg-output "is located in stack of thread T0 at offset.*" } */
+/* { dg-output "\'s1\' <== Memory access at offset \[0-9\]+ partially overflows this variable" } */
Index: gcc/testsuite/c-c++-common/asan/strcasestr-2.c
===
--- gcc/testsuite/c-c++-common/asan/strcasestr-2.c	(revision 0)
+++ gcc/testsuite/c-c++-common/asan/strcasestr-2.c	(working copy)
@@ -0,0 +1,30 @@
+/* { dg-do run } */
+/* { dg-set-target-env-var ASAN_OPTIONS "strict_string_checks=true" } */
+/* { dg-shouldfail "asan" } */
+
+#include 
+#include 
+
+#ifndef __cplusplus
+#define _GNU_SOURCE
+#else
+extern "C"
+#endif
+char *
+strcasestr(const char *haystack, const char *needle);
+
+int main(int argc, char **argv) {
+  char *r = 0;
+  char s1[] = "ab";
+  char s2[4] = "cba";
+  __asan_poison_memory_region ((char *)&s2[2], 2);
+  r = strcasestr(s1, s2);
+  assert(r == 0);
+  return 0;
+}
+
+/* { dg-output "READ of size 4 at .* thread T0.*" } */
+/* { dg-output ".*(main)?.*strcasestr-2.(c:21)?.*" } */
+/* { dg-output "is located in stack of thread T0 at offset.*" } */
+/* { dg-output "\'s2\' <== Memory access at offset \[0-9\]+ partially overflows this variable" } */
Index: gcc/testsuite/c-c++-common/asan/strcspn-1.c
===
--- gcc/testsuite/c-c++-common/asan/strcspn-1.c	(revision 0)
+++ gcc/testsuite/c-c++-common/asan/strcspn-1.c	(working copy)
@@ -0,0 +1,26 @@
+/* { dg-do run } */
+/* { dg-set-target-env-var ASAN_OPTIONS "strict_string_checks=true" } */
+/* { dg-shouldfail "asan" } */
+
+#include 
+#include 
+#ifdef __cplusplus
+extern "C"
+#endif
+__SIZE_TYPE__
+strcspn (const char *s, const char *reject);
+
+int main(int argc, char **argv) {
+  __SIZE_TYPE__ r;
+  char s2[] = "ab";
+  char s1[4] = "caB";
+  __asan_poison_memory_region ((char *)&s1[2], 2);
+  r = strcspn(s1, s2);
+  assert(r == 1);
+  return 0;
+}
+
+/* { dg-output "READ of size 4 at .* thread T0.*" } */
+/* { dg-output ".*(main)?.*strcspn-1.(c:18)?.*" } */
+/* { dg-output "is located in stack of thread T0 at offset.*" } */
+/* { dg-output "\'s1\' <== Memory access at offset \[0-9\]+ partially overflows this variable" } */
Index: gcc/testsuite/c-c++-common/asan/strcspn-2.c
==

[PATCH][4.9] Backport fix for PR sanitizer/64820.

2015-11-18 Thread Maxim Ostapenko

Hi,

this small patch fixes the logic in ASan vs SSP interaction to provide 
correct "size" parameter to asan_stack_malloc_[N] routines. With current 
logic, we would have assertion failure in libsanitizer in UAR mode on 
32-bit targets due to wrong granularity of resulting addr + size address.


Regtested via make check RUNTESTFLAGS="--target_board=unix'{-m32,-m64}' 
-j12 on x86_64-unknown-linux-gnu and bootstrapped on 
x86_64-unknown-linux-gnu.


Ok for gcc-4_9-branch?

-Maxim
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 4df00bf..f1f2744 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,14 @@
+2015-11-18  Max Ostapenko  
+
+	Backport from mainline.
+	2015-03-16  Max Ostapenko  
+
+	PR sanitizer/64820
+	* cfgexpand.c (align_base): New function.
+	(alloc_stack_frame_space): Call it.
+	(expand_stack_vars): Align prev_frame to be sure
+	data->asan_vec elements aligned properly.
+
 2015-11-12  Eric Botcazou  
 
 	PR target/67265
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index 14511e1..8bebd85 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -248,6 +248,15 @@ align_local_variable (tree decl)
   return align / BITS_PER_UNIT;
 }
 
+/* Align given offset BASE with ALIGN.  Truncate up if ALIGN_UP is true,
+   down otherwise.  Return truncated BASE value.  */
+
+static inline unsigned HOST_WIDE_INT
+align_base (HOST_WIDE_INT base, unsigned HOST_WIDE_INT align, bool align_up)
+{
+  return align_up ? (base + align - 1) & -align : base & -align;
+}
+
 /* Allocate SIZE bytes at byte alignment ALIGN from the stack frame.
Return the frame offset.  */
 
@@ -256,20 +265,17 @@ alloc_stack_frame_space (HOST_WIDE_INT size, unsigned HOST_WIDE_INT align)
 {
   HOST_WIDE_INT offset, new_frame_offset;
 
-  new_frame_offset = frame_offset;
   if (FRAME_GROWS_DOWNWARD)
 {
-  new_frame_offset -= size + frame_phase;
-  new_frame_offset &= -align;
-  new_frame_offset += frame_phase;
+  new_frame_offset
+	= align_base (frame_offset - frame_phase - size,
+		  align, false) + frame_phase;
   offset = new_frame_offset;
 }
   else
 {
-  new_frame_offset -= frame_phase;
-  new_frame_offset += align - 1;
-  new_frame_offset &= -align;
-  new_frame_offset += frame_phase;
+  new_frame_offset
+	= align_base (frame_offset - frame_phase, align, true) + frame_phase;
   offset = new_frame_offset;
   new_frame_offset += size;
 }
@@ -983,13 +989,16 @@ expand_stack_vars (bool (*pred) (size_t), struct stack_vars_data *data)
 	  base = virtual_stack_vars_rtx;
 	  if ((flag_sanitize & SANITIZE_ADDRESS) && ASAN_STACK && pred)
 	{
-	  HOST_WIDE_INT prev_offset = frame_offset;
+	  HOST_WIDE_INT prev_offset
+		= align_base (frame_offset,
+			  MAX (alignb, ASAN_RED_ZONE_SIZE),
+			  FRAME_GROWS_DOWNWARD);
 	  tree repr_decl = NULL_TREE;
-
 	  offset
 		= alloc_stack_frame_space (stack_vars[i].size
 	   + ASAN_RED_ZONE_SIZE,
 	   MAX (alignb, ASAN_RED_ZONE_SIZE));
+
 	  data->asan_vec.safe_push (prev_offset);
 	  data->asan_vec.safe_push (offset + stack_vars[i].size);
 	  /* Find best representative of the partition.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 0072132..3d565ec 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,11 @@
+2015-11-18  Max Ostapenko  
+
+	Backport from mainline.
+	2015-03-16  Max Ostapenko  
+
+	PR sanitizer/64820
+	* c-c++-common/asan/pr64820.c: New test.
+
 2015-11-12  Eric Botcazou  
 
 	* gcc.target/i386/pr67265-2.c: New test.
diff --git a/gcc/testsuite/c-c++-common/asan/pr64820.c b/gcc/testsuite/c-c++-common/asan/pr64820.c
new file mode 100644
index 000..885a662
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/asan/pr64820.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+/* { dg-require-effective-target fstack_protector } */
+/* { dg-options "-fstack-protector-strong" } */
+/* { dg-set-target-env-var ASAN_OPTIONS "detect_stack_use_after_return=1" } */
+/* { dg-shouldfail "asan" } */
+
+__attribute__((noinline))
+char *Ident(char *x) {
+  return x;
+}
+
+__attribute__((noinline))
+char *Func1() {
+  char local[1 << 12];
+  return Ident(local);
+}
+
+__attribute__((noinline))
+void Func2(char *x) {
+  *x = 1;
+}
+int main(int argc, char **argv) {
+  Func2(Func1());
+  return 0;
+}
+
+/* { dg-output "AddressSanitizer: stack-use-after-return on address 0x\[0-9a-f\]+\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "WRITE of size 1 at .* thread T0.*" } */
+/* { dg-output "#0.*(Func2)?.*pr64820.(c:21)?.*" } */
+/* { dg-output "is located in stack of thread T0 at offset.*" } */
+/* { dg-output "\'local\' <== Memory access at offset 32 is inside this variable" } */


Backport important ASan features from upstream.

2015-11-19 Thread Maxim Ostapenko

Hi!

Since the last sanitizer library merge to GCC happened, some new useful 
features were applied upstream. In particular, the most significant are:


* The shadow offset for ASan was unified on Aarch64 for 39 and 42 VMAs 
(http://reviews.llvm.org/D13782). AFAU, this change wouldn't require any 
additional support from compiler side, because the shadow offset is the 
same as for 39-bit VMA (36) .
* Optional ASan recovery functionality was merged to sanitizer library 
(http://reviews.llvm.org/D12318). This feature seems to be very helpful 
in complex systems where we may want to proceed to work even in case of 
bug was detected. However, to access this functionality, we'll need to 
implement new asan_report_{store, load}{1, 2, 4, 8, 16, N}_noabort 
callbacks in compiler. This is probably unacceptable for stage 3.


I think it would be nice to have unified shadow offset on Aarch64 for 39 
and 42 VMAs even in GCC 6 (enabling ASan recovery would be nice too, but 
it's much harder).


So, my question is: is it acceptable to backport these features from 
upstream without touching compiler side? If so, I see two options here:


- Perform sanitizer library merge to GCC without changing compiler side.
- Cherry-pick the patch for AArch64 on top of current trunk.

Thanks,
-Maxim


Re: Backport important ASan features from upstream.

2015-11-19 Thread Maxim Ostapenko

On 19/11/15 13:18, Jakub Jelinek wrote:

On Thu, Nov 19, 2015 at 11:19:23AM +0300, Maxim Ostapenko wrote:

Hi!

Since the last sanitizer library merge to GCC happened, some new useful
features were applied upstream. In particular, the most significant are:

* The shadow offset for ASan was unified on Aarch64 for 39 and 42 VMAs
(http://reviews.llvm.org/D13782). AFAU, this change wouldn't require any
additional support from compiler side, because the shadow offset is the same
as for 39-bit VMA (36) .
* Optional ASan recovery functionality was merged to sanitizer library
(http://reviews.llvm.org/D12318). This feature seems to be very helpful in
complex systems where we may want to proceed to work even in case of bug was
detected. However, to access this functionality, we'll need to implement new
asan_report_{store, load}{1, 2, 4, 8, 16, N}_noabort callbacks in compiler.
This is probably unacceptable for stage 3.

No, those are already there (for -fsanitize{,-recover}=kernel-address).
IMHO all you need is remove:
   if (opts->x_flag_sanitize_recover & SANITIZE_USER_ADDRESS)
 error_at (loc, "-fsanitize-recover=address is not supported");
in opts.c (finish_options), and in asan.c (asan_expand_check_ifn)
change
   bool recover_p
 = (flag_sanitize & flag_sanitize_recover & SANITIZE_KERNEL_ADDRESS) != 0;
to say:
   bool recover_p;
   if (flag_sanitize & SANITIZE_USER_ADDRESS)
 recover_p = (flag_sanitize_recover & SANITIZE_USER_ADDRESS) != 0;
   else
 recover_p = (flag_sanitize_recover & SANITIZE_KERNEL_ADDRESS) != 0;
(plus add some testsuite coverage).
This is small enough change that I'm ok with an exception for this.


I think it would be nice to have unified shadow offset on Aarch64 for 39 and
42 VMAs even in GCC 6 (enabling ASan recovery would be nice too, but it's
much harder).

So, my question is: is it acceptable to backport these features from
upstream without touching compiler side? If so, I see two options here:

- Perform sanitizer library merge to GCC without changing compiler side.

And at this point I also prefer the above, rather than cherry-picking, of
course later on in the process cherry-picking will be desirable instead.


Great, thanks! I'll try to perform another merge as soon as possible.




- Cherry-pick the patch for AArch64 on top of current trunk.

Jakub





[PATCH 0/2] Libsanitizer merge from upstream r253555.

2015-11-22 Thread Maxim Ostapenko

Hi!

Following recent discussion 
(https://gcc.gnu.org/ml/gcc-patches/2015-11/msg02310.html), I would like 
to merge recent sanitizer library to GCC to make available new useful 
features from upstream in GCC 6:


* The shadow offset for ASan was unified on Aarch64 for 39 and 42 VMAs 
(http://reviews.llvm.org/D13782). This change would not require any new 
code into compiler side.
* Optional ASan recovery functionality was merged to sanitizer library 
(http://reviews.llvm.org/D12318). This feature requires some minimal 
compiler changes that I'll post below.
* LSan was finally fixed and enabled for AArch64 
(http://reviews.llvm.org/rL250898).


The first patch is the library merge itself. I've also applied 3 GCC 
specific patches here (I don't post them separately to avoid polluting 
ChangeLog):


* Patch for SPARC by David S. Miller 
(https://gcc.gnu.org/ml/gcc-patches/2015-10/msg01855.html).
* Disable ODR violation detection 
(https://gcc.gnu.org/ml/gcc-patches/2015-10/msg01856.html).
* Adjust the fix for https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61771 
to extract the last PC from the stack frame if no valid FP is available 
for ARM (https://gcc.gnu.org/ml/gcc-patches/2015-10/msg01857.html).


The second one reflects to corresponding compiler changes. In 
particular, it just enables -fsanitize-recover=address switch and 
migrates two small testcases from upstream.


Regtested and bootstrapped on {x86_64, aarch64}-unknown-linux-gnu and 
arm-linux-gnueabi. Is it OK for mainline?


[PATCH 2/2] Libsanitizer merge from upstream r253555.

2015-11-22 Thread Maxim Ostapenko
This patch reflects to corresponding compiler changes. In particular, it 
just enables -fsanitize-recover=address switch and migrates two small 
testcases from upstream. I don't backport other stress tests because 
they are heavy and have unstable output.


-Maxim
gcc/testsuite/ChangeLog:

2015-11-23  Maxim Ostapenko  

	* c-c++-common/asan/halt_on_error-1.c: New test.
	* c-c++-common/asan/halt_on_error-2.c: Likewise.

gcc/ChangeLog:

2015-11-23  Maxim Ostapenko  

	* opts.c (finish_options): Allow -fsanitize-recover=address for
	userspace sanitization.
	* asan.c (asan_expand_check_ifn): Redefine recover_p.
	* doc/invoke.texi (fsanitize-recover): Update documentation.

Index: gcc/asan.c
===
--- gcc/asan.c	(revision 230597)
+++ gcc/asan.c	(working copy)
@@ -2533,10 +2533,12 @@
 {
   gimple *g = gsi_stmt (*iter);
   location_t loc = gimple_location (g);
+  bool recover_p;
+  if (flag_sanitize & SANITIZE_USER_ADDRESS)
+recover_p = (flag_sanitize_recover & SANITIZE_USER_ADDRESS) != 0;
+  else
+recover_p = (flag_sanitize_recover & SANITIZE_KERNEL_ADDRESS) != 0;
 
-  bool recover_p
-= (flag_sanitize & flag_sanitize_recover & SANITIZE_KERNEL_ADDRESS) != 0;
-
   HOST_WIDE_INT flags = tree_to_shwi (gimple_call_arg (g, 0));
   gcc_assert (flags < ASAN_CHECK_LAST);
   bool is_scalar_access = (flags & ASAN_CHECK_SCALAR_ACCESS) != 0;
Index: gcc/doc/invoke.texi
===
--- gcc/doc/invoke.texi	(revision 230597)
+++ gcc/doc/invoke.texi	(working copy)
@@ -6111,8 +6111,10 @@
 
 Currently this feature only works for @option{-fsanitize=undefined} (and its suboptions
 except for @option{-fsanitize=unreachable} and @option{-fsanitize=return}),
-@option{-fsanitize=float-cast-overflow}, @option{-fsanitize=float-divide-by-zero} and
-@option{-fsanitize=kernel-address}.  For these sanitizers error recovery is turned on by default.
+@option{-fsanitize=float-cast-overflow}, @option{-fsanitize=float-divide-by-zero},
+@option{-fsanitize=kernel-address} and @option{-fsanitize=address}.
+For these sanitizers error recovery is turned on by default, except @option{-fsanitize=address},
+for which this feature is experimental.
 @option{-fsanitize-recover=all} and @option{-fno-sanitize-recover=all} is also
 accepted, the former enables recovery for all sanitizers that support it,
 the latter disables recovery for all sanitizers that support it.
Index: gcc/opts.c
===
--- gcc/opts.c	(revision 230597)
+++ gcc/opts.c	(working copy)
@@ -941,11 +941,8 @@
 	  "-fsanitize=address and -fsanitize=kernel-address "
 	  "are incompatible with -fsanitize=thread");
 
-  /* Error recovery is not allowed for ASan and TSan.  */
+  /* Error recovery is not allowed for LSan and TSan.  */
 
-  if (opts->x_flag_sanitize_recover & SANITIZE_USER_ADDRESS)
-error_at (loc, "-fsanitize-recover=address is not supported");
-
   if (opts->x_flag_sanitize_recover & SANITIZE_THREAD)
 error_at (loc, "-fsanitize-recover=thread is not supported");
 
Index: gcc/testsuite/c-c++-common/asan/halt_on_error-1.c
===
--- gcc/testsuite/c-c++-common/asan/halt_on_error-1.c	(revision 0)
+++ gcc/testsuite/c-c++-common/asan/halt_on_error-1.c	(working copy)
@@ -0,0 +1,23 @@
+/* Test recovery mode.  */
+/* { dg-do run } */
+/* { dg-options "-fsanitize-recover=address" } */
+/* { dg-set-target-env-var ASAN_OPTIONS "halt_on_error=false" } */
+
+#include 
+
+volatile int ten = 10;
+
+int main() {
+  char x[10];
+  memset(x, 0, 11);
+  asm volatile ("" : : : "memory");
+  volatile int res = x[ten];
+  x[ten] = res + 3;
+  res = x[ten];
+  return 0;
+}
+
+/* { dg-output "WRITE of size 11 at 0x\[0-9a-f\]+ thread T0\[^\n\r]*(\n|\r\n|\r).*" } */
+/* { dg-output "\[^\n\r]*READ of size 1 at 0x\[0-9a-f\]+ thread T0\[^\n\r]*(\n|\r\n|\r).*" } */
+/* { dg-output "\[^\n\r]*WRITE of size 1 at 0x\[0-9a-f\]+ thread T0\[^\n\r]*(\n|\r\n|\r).*" } */
+/* { dg-output "\[^\n\r]*READ of size 1 at 0x\[0-9a-f\]+ thread T0\[^\n\r]*(\n|\r\n|\r).*" } */
Index: gcc/testsuite/c-c++-common/asan/halt_on_error-2.c
===
--- gcc/testsuite/c-c++-common/asan/halt_on_error-2.c	(revision 0)
+++ gcc/testsuite/c-c++-common/asan/halt_on_error-2.c	(working copy)
@@ -0,0 +1,24 @@
+/* Test recovery mode.  */
+/* { dg-do run } */
+/* { dg-options "-fsanitize-recover=address" } */
+/* { dg-set-target-env-var ASAN_OPTIONS "halt_on_error=true" } */
+/* { dg-shouldfail "asan" } */
+
+#include 
+
+volatile int ten = 10;
+
+int main() {
+  char x[10];
+  memset(x, 0, 11);
+  asm volatile ("" : : : "mem

Re: [PATCH 1/2] Libsanitizer merge from upstream r253555.

2015-11-23 Thread Maxim Ostapenko

+ Adhemerval

Christophe, it looks like your kernel headers (asm/ptrace.h) don't 
contain ARM_VFPREGS_SIZE. Do you use old kernel version?


-Maxim

On 23/11/15 15:16, Christophe Lyon wrote:

On 23 November 2015 at 09:07, Jakub Jelinek  wrote:

On Mon, Nov 23, 2015 at 10:46:33AM +0300, Maxim Ostapenko wrote:

Index: libsanitizer/configure.ac
===
--- libsanitizer/configure.ac (revision 230597)
+++ libsanitizer/configure.ac (working copy)
@@ -136,6 +136,12 @@
  esac
  AM_CONDITIONAL(USING_MAC_INTERPOSE, $MAC_INTERPOSE)

+case "$target" in
+  aarch64-*-linux*) tsan_aarch64=true ;;
+  *) tsan_aarch64=false ;;
+esac
+AM_CONDITIONAL(TSAN_AARCH64, $tsan_aarch64)
+

I don't understand the purpose of the above.


Index: libsanitizer/configure.tgt
===
--- libsanitizer/configure.tgt(revision 230597)
+++ libsanitizer/configure.tgt(working copy)
@@ -37,6 +37,8 @@
aarch64*-*-linux*)
   if test x$ac_cv_sizeof_void_p = x8; then
   TSAN_SUPPORTED=yes
+ LSAN_SUPPORTED=yes
+ TSAN_TARGET_DEPENDENT_OBJECTS=tsan_rtl_aarch64.lo
   fi
   ;;
x86_64-*-darwin[1]* | i?86-*-darwin[1]*)

You already have this.


Index: libsanitizer/tsan/Makefile.am
===
--- libsanitizer/tsan/Makefile.am (revision 230597)
+++ libsanitizer/tsan/Makefile.am (working copy)
@@ -21,6 +21,8 @@
   tsan_interface_atomic.cc \
   tsan_interface.cc \
   tsan_interface_java.cc \
+ tsan_libdispatch_mac.cc \
+ tsan_malloc_mac.cc \
   tsan_md5.cc \
   tsan_mman.cc \
   tsan_mutex.cc \
@@ -28,6 +30,7 @@
   tsan_new_delete.cc \
   tsan_platform_linux.cc \
   tsan_platform_mac.cc \
+ tsan_platform_posix.cc \
   tsan_platform_windows.cc \
   tsan_report.cc \
   tsan_rtl.cc \
@@ -41,7 +44,11 @@
   tsan_sync.cc

  libtsan_la_SOURCES = $(tsan_files)
+if TSAN_AARCH64
+EXTRA_libtsan_la_SOURCES = tsan_rtl_aarch64.S
+else
  EXTRA_libtsan_la_SOURCES = tsan_rtl_amd64.S
+endif

And if I understand automake manual, you can list in there both
EXTRA_libtsan_la_SOURCES = tsan_rtl_amd64.S tsan_rtl_aarch64.S
unconditionally, and what object actually gets linked in is picked from the
$(TSAN_TARGET_DEPENDENT_OBJECTS) (and similarly dependencies).

Otherwise LGTM.

Since this commit (r230739), I've noticed that the arm*linux* builds fail:
libtool: compile:
/tmp/1800227_1.tmpdir/aci-gcc-fsf/builds/gcc-fsf-gccsrc/obj-arm-none-linux-gnueabi/gcc3/./gcc/xgcc
-shared-libgcc -B/tmp/1800227_1.tmpdir/aci-gcc-fsf/builds/g
cc-fsf-gccsrc/obj-arm-none-linux-gnueabi/gcc3/./gcc -nostdinc++
-L/tmp/1800227_1.tmpdir/aci-gcc-fsf/builds/gcc-fsf-gccsrc/obj-arm-none-linux-gnueabi/gcc3/arm-none-linux-gnueabi/
libstdc++-v3/src
-L/tmp/1800227_1.tmpdir/aci-gcc-fsf/builds/gcc-fsf-gccsrc/obj-arm-none-linux-gnueabi/gcc3/arm-none-linux-gnueabi/libstdc++-v3/src/.libs
-L/tmp/1800227_1.tmpdir/
aci-gcc-fsf/builds/gcc-fsf-gccsrc/obj-arm-none-linux-gnueabi/gcc3/arm-none-linux-gnueabi/libstdc++-v3/libsupc++/.libs
-B/tmp/1800227_1.tmpdir/aci-gcc-fsf/builds/gcc-fsf-gccsrc/t
ools/arm-none-linux-gnueabi/bin/
-B/tmp/1800227_1.tmpdir/aci-gcc-fsf/builds/gcc-fsf-gccsrc/tools/arm-none-linux-gnueabi/lib/
-isystem /tmp/1800227_1.tmpdir/aci-gcc-fsf/builds/gc
c-fsf-gccsrc/tools/arm-none-linux-gnueabi/include -isystem
/tmp/1800227_1.tmpdir/aci-gcc-fsf/builds/gcc-fsf-gccsrc/tools/arm-none-linux-gnueabi/sys-include
-D_GNU_SOURCE -D_DEBU
G -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS
-D__STDC_LIMIT_MACROS -DHAVE_RPC_XDR_H=1 -DHAVE_TIRPC_RPC_XDR_H=0 -I.
-I/tmp/1800227_1.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsr
c/libsanitizer/sanitizer_common -I.. -I
/tmp/1800227_1.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libsanitizer/include
-isystem /tmp/1800227_1.tmpdir/aci-gcc-fsf/sources/gcc-fsf/
gccsrc/libsanitizer/include/system -Wall -W -Wno-unused-parameter
-Wwrite-strings -pedantic -Wno-long-long -fPIC -fno-builtin
-fno-exceptions -fno-rtti -fomit-frame-pointer -fun
wind-tables -fvisibility=hidden -Wno-variadic-macros
-I../../libstdc++-v3/include
-I../../libstdc++-v3/include/arm-none-linux-gnueabi
-I/tmp/1800227_1.tmpdir/aci-gcc-fsf/sources
/gcc-fsf/gccsrc/libsanitizer/../libstdc++-v3/libsupc++ -std=gnu++11
-DSANITIZER_LIBBACKTRACE -DSANITIZER_CP_DEMANGLE -I
/tmp/1800227_1.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/
libsanitizer/../libbacktrace -I ../libbacktrace -I
/tmp/1800227_1.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libsanitizer/../include
-include /tmp/1800227_1.tmpdir/aci-gcc-fsf/so
urces/gcc-fsf/gccsrc/libsanitizer/libbacktrace/backtrace-rename.h -g
-O2 -D_GNU_SOURCE -MT sanitizer_platform_limits_posix.lo -MD -MP -MF
.deps/sanitizer_platform_limits_posix.T
po -c 
/tmp/1800227_1.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.

Re: [PATCH 1/2] Libsanitizer merge from upstream r253555.

2015-11-23 Thread Maxim Ostapenko

On 23/11/15 16:00, Christophe Lyon wrote:

On 23 November 2015 at 13:41, Jakub Jelinek  wrote:

On Mon, Nov 23, 2015 at 03:33:57PM +0300, Maxim Ostapenko wrote:

+ Adhemerval

Christophe, it looks like your kernel headers (asm/ptrace.h) don't contain
ARM_VFPREGS_SIZE. Do you use old kernel version?

Yes, I do use old kernel headers.
I could upgrade them, but I tend to avoid changing versions (binutils,
glibc, newlib, kernel headers) unless really necessary.


Unlike LLVM, we do care to support older kernel headers.
So, if it is say a define, you could add
libsanitizer/include/system/linux/ptrace.h
or
libsanitizer/include/system/asm/ptrace.h
that would #include_next the original header and ifdef __arm__ and
that define is not defined (or some other condition, kernel version etc.),
define it.

 Jakub

So, given Jakub's answer I'll not upgrade them yet on my side :-)




Yeah, right. I've asked about kernel headers just to make sure I 
correctly understand the issue.


Actually, I see such code in 
lib/sanitizer_common/sanitizer_platform_limits_posix.cc:


#if defined(PTRACE_GETVFPREGS) && defined(PTRACE_SETVFPREGS)
  int ptrace_getvfpregs = PTRACE_GETVFPREGS;
  int ptrace_setvfpregs = PTRACE_SETVFPREGS;
#else
  int ptrace_getvfpregs = -1;
  int ptrace_setvfpregs = -1;
#endif

and in ptrace interceptor:

 else if (request == ptrace_setvfpregs)
COMMON_INTERCEPTOR_READ_RANGE(ctx, data, 
struct_user_vfpregs_struct_sz);

 else if (request == ptrace_getvfpregs)
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, 
struct_user_vfpregs_struct_sz)


So, perhaps we can do the same thing with ARM_VFPREGS_SIZE, something 
like this?


diff --git 
a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc 
b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc

index 9866cc9..20ff224 100644
--- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc
@@ -323,10 +323,14 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr);
   unsigned struct_user_fpxregs_struct_sz = sizeof(struct 
user_fpxregs_struct);

 #endif // __x86_64 || __mips64 || __powerpc64__ || __aarch64__ || __arm__
 #ifdef __arm__
+#if defined(ARM_VFPREGS_SIZE)
   unsigned struct_user_vfpregs_struct_sz = ARM_VFPREGS_SIZE;
 #else
   unsigned struct_user_vfpregs_struct_sz = 0;
 #endif
+#else
+  unsigned struct_user_vfpregs_struct_sz = 0;
+#endif





Re: [PATCH 1/2] Libsanitizer merge from upstream r253555.

2015-11-23 Thread Maxim Ostapenko

On 23/11/15 16:24, Jakub Jelinek wrote:

On Mon, Nov 23, 2015 at 04:21:34PM +0300, Maxim Ostapenko wrote:

Yeah, right. I've asked about kernel headers just to make sure I correctly
understand the issue.

Actually, I see such code in
lib/sanitizer_common/sanitizer_platform_limits_posix.cc:

#if defined(PTRACE_GETVFPREGS) && defined(PTRACE_SETVFPREGS)
   int ptrace_getvfpregs = PTRACE_GETVFPREGS;
   int ptrace_setvfpregs = PTRACE_SETVFPREGS;
#else
   int ptrace_getvfpregs = -1;
   int ptrace_setvfpregs = -1;
#endif

and in ptrace interceptor:

  else if (request == ptrace_setvfpregs)
 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_vfpregs_struct_sz);
  else if (request == ptrace_getvfpregs)
 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_vfpregs_struct_sz)

So, perhaps we can do the same thing with ARM_VFPREGS_SIZE, something like
this?

diff --git
a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc
b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc
index 9866cc9..20ff224 100644
--- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc
@@ -323,10 +323,14 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr);
unsigned struct_user_fpxregs_struct_sz = sizeof(struct
user_fpxregs_struct);
  #endif // __x86_64 || __mips64 || __powerpc64__ || __aarch64__ || __arm__
  #ifdef __arm__
+#if defined(ARM_VFPREGS_SIZE)
unsigned struct_user_vfpregs_struct_sz = ARM_VFPREGS_SIZE;
  #else
unsigned struct_user_vfpregs_struct_sz = 0;
  #endif
+#else
+  unsigned struct_user_vfpregs_struct_sz = 0;
+#endif

Maybe, but then it would need to be approved upstream.
If you just define ARM_VFPREGS_SIZE to 0 or whatever else in
the GCC owned wrapper headers, you can avoid that.
I guess talk to upstream.

Jakub




Ok, I posted a fix to upstream (http://reviews.llvm.org/D14921) 
yesterday, but it's still not reviewed. So, I'm wondering if I should 
fix the issue locally?

Attaching proposed fix following Jakub's suggestion.

Christophe could you try the patch?
diff --git a/libsanitizer/ChangeLog b/libsanitizer/ChangeLog
index b97fc7d..c392c57 100644
--- a/libsanitizer/ChangeLog
+++ b/libsanitizer/ChangeLog
@@ -1,3 +1,7 @@
+2015-11-24  Maxim Ostapenko  
+
+	* include/system/linux/asm/ptrace.h: New header.
+
 2015-11-23  Maxim Ostapenko  
 
 	* All source files: Merge from upstream r253555.
diff --git a/libsanitizer/include/system/linux/asm/ptrace.h b/libsanitizer/include/system/linux/asm/ptrace.h
new file mode 100644
index 000..dbdd58b
--- /dev/null
+++ b/libsanitizer/include/system/linux/asm/ptrace.h
@@ -0,0 +1,8 @@
+#include_next 
+#if defined(__arm__)
+#ifndef ARM_VFPREGS_SIZE
+/* The size of the user-visible VFP state as seen by PTRACE_GET/SETVFPREGS
+   and core dumps.  */
+#define ARM_VFPREGS_SIZE ( 32 * 8 /*fpregs*/ + 4 /*fpscr*/ )
+#endif
+#endif


Re: [PATCH 1/2] Libsanitizer merge from upstream r253555.

2015-11-24 Thread Maxim Ostapenko

On 24/11/15 11:25, Jakub Jelinek wrote:

On Tue, Nov 24, 2015 at 10:51:05AM +0300, Maxim Ostapenko wrote:

Ok, I posted a fix to upstream (http://reviews.llvm.org/D14921) yesterday,
but it's still not reviewed. So, I'm wondering if I should fix the issue
locally?
Attaching proposed fix following Jakub's suggestion.

Christophe could you try the patch?
diff --git a/libsanitizer/ChangeLog b/libsanitizer/ChangeLog
index b97fc7d..c392c57 100644
--- a/libsanitizer/ChangeLog
+++ b/libsanitizer/ChangeLog
@@ -1,3 +1,7 @@
+2015-11-24  Maxim Ostapenko  
+
+   * include/system/linux/asm/ptrace.h: New header.
+
  2015-11-23  Maxim Ostapenko  
  
  	* All source files: Merge from upstream r253555.

diff --git a/libsanitizer/include/system/linux/asm/ptrace.h 
b/libsanitizer/include/system/linux/asm/ptrace.h
new file mode 100644
index 000..dbdd58b
--- /dev/null
+++ b/libsanitizer/include/system/linux/asm/ptrace.h
@@ -0,0 +1,8 @@
+#include_next 
+#if defined(__arm__)
+#ifndef ARM_VFPREGS_SIZE
+/* The size of the user-visible VFP state as seen by PTRACE_GET/SETVFPREGS
+   and core dumps.  */
+#define ARM_VFPREGS_SIZE ( 32 * 8 /*fpregs*/ + 4 /*fpscr*/ )
+#endif
+#endif

You could have just used #if defined(__arm__) && !defined(ARM_VFPREGS_SIZE)
or #ifdef __arm__
or #if !defined(ARM_VFPREGS_SIZE).
Mixing if defined with ifndef on the next line is just weird.
And, you should mention which kernel version introduced ARM_VFPREGS_SIZE
macro (I believe it was 2011-ish, but have not checked exact kernel
version).

Jakub

Ok, does it look better now?

-Maxim
diff --git a/libsanitizer/ChangeLog b/libsanitizer/ChangeLog
index b97fc7d..c392c57 100644
--- a/libsanitizer/ChangeLog
+++ b/libsanitizer/ChangeLog
@@ -1,3 +1,7 @@
+2015-11-24  Maxim Ostapenko  
+
+	* include/system/linux/asm/ptrace.h: New header.
+
 2015-11-23  Maxim Ostapenko  
 
 	* All source files: Merge from upstream r253555.
diff --git a/libsanitizer/include/system/linux/asm/ptrace.h b/libsanitizer/include/system/linux/asm/ptrace.h
new file mode 100644
index 000..d4249fe
--- /dev/null
+++ b/libsanitizer/include/system/linux/asm/ptrace.h
@@ -0,0 +1,7 @@
+#include_next 
+/* ARM_VFPREGS_SIZE has been added in 3.0 */
+#if defined(__arm__) && !defined(ARM_VFPREGS_SIZE)
+/* The size of the user-visible VFP state as seen by PTRACE_GET/SETVFPREGS
+   and core dumps.  */
+#define ARM_VFPREGS_SIZE ( 32 * 8 /*fpregs*/ + 4 /*fpscr*/ )
+#endif


Re: [PATCH 1/2] Libsanitizer merge from upstream r253555.

2015-11-24 Thread Maxim Ostapenko

On 24/11/15 11:38, Jakub Jelinek wrote:

On Tue, Nov 24, 2015 at 11:36:20AM +0300, Maxim Ostapenko wrote:

Ok, does it look better now?

Sure, this is ok for trunk.


diff --git a/libsanitizer/ChangeLog b/libsanitizer/ChangeLog
index b97fc7d..c392c57 100644
--- a/libsanitizer/ChangeLog
+++ b/libsanitizer/ChangeLog
@@ -1,3 +1,7 @@
+2015-11-24  Maxim Ostapenko  
+
+   * include/system/linux/asm/ptrace.h: New header.
+
  2015-11-23  Maxim Ostapenko  
  
  	* All source files: Merge from upstream r253555.

diff --git a/libsanitizer/include/system/linux/asm/ptrace.h 
b/libsanitizer/include/system/linux/asm/ptrace.h
new file mode 100644
index 000..d4249fe
--- /dev/null
+++ b/libsanitizer/include/system/linux/asm/ptrace.h
@@ -0,0 +1,7 @@
+#include_next 
+/* ARM_VFPREGS_SIZE has been added in 3.0 */
+#if defined(__arm__) && !defined(ARM_VFPREGS_SIZE)
+/* The size of the user-visible VFP state as seen by PTRACE_GET/SETVFPREGS
+   and core dumps.  */
+#define ARM_VFPREGS_SIZE ( 32 * 8 /*fpregs*/ + 4 /*fpscr*/ )
+#endif

Jakub



Thanks, applied as r230790.

Christophe, please let me know if it cured your build.

-Maxim


Re: [PATCH 1/2] Libsanitizer merge from upstream r253555.

2015-11-24 Thread Maxim Ostapenko

On 24/11/15 14:27, Jakub Jelinek wrote:

On Tue, Nov 24, 2015 at 12:23:05PM +0100, Christophe Lyon wrote:

On 24 November 2015 at 12:12, Jakub Jelinek  wrote:

On Tue, Nov 24, 2015 at 12:08:13PM +0100, Christophe Lyon wrote:

Sure.
I had a build in progress with your proposed patch, but it didn't
complete before you committed :-)


So... it still does not work for me. I re-tried several times, made sure I had
everything cleanup before starting new builds from scratch, hence the delay.

I'm still seeing:
/tmp/2050111_1.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc:326:44:
error: 'ARM_VFPREGS_SIZE' was not declared in this scope
unsigned struct_user_vfpregs_struct_sz = ARM_VFPREGS_SIZE;

So cut'n'paste the sanitizer_platform_limits_posix.cc compilation command
line and replace -c with -E -dD, then look if the wrapper asm/ptrace.h is
included or not and why?


It pulls the one from the sysroot:
sysroot-arm-none-linux-gnueabihf/usr/include/asm/ptrace.h
(I configure GCC --with-sysroot=XXX)

Then you should figure out where the sysroot include dirs are added in the
sanitizer_common/Makefile and make sure -isystem $(top_srcdir)/include/system
comes before that.

Jakub



It seems that I placed new header into wrong directory, it should be
libsanitizer/include/system/asm/ptrace.h
instead of
libsanitizer/include/system/linux/asm/ptrace.h

This should work:
$ cat .libs/sanitizer_platform_limits_posix.i
.
# 1 
"/home/max/workspace/downloads/gcc/libsanitizer/include/system/asm/ptrace.h" 
1 3 4
# 1 
"/home/max/install/armv7l-tizen/armv7l-tizen-linux-gnueabi/sys-root/usr/include/asm/ptrace.h" 
1 3 4
# 11 
"/home/max/install/armv7l-tizen/armv7l-tizen-linux-gnueabi/sys-root/usr/include/asm/ptrace.h" 
3 4

#define __ASM_ARM_PTRACE_H~

# 1 
"/home/max/install/armv7l-tizen/armv7l-tizen-linux-gnueabi/sys-root/usr/include/asm/hwcap.h" 
1 3 4


#define __ASMARM_HWCAP_H~
.
diff --git a/libsanitizer/ChangeLog b/libsanitizer/ChangeLog
index c392c57..895d3bd 100644
--- a/libsanitizer/ChangeLog
+++ b/libsanitizer/ChangeLog
@@ -1,5 +1,10 @@
 2015-11-24  Maxim Ostapenko  
 
+	* include/system/linux/asm/ptrace.h: Move to ...
+	* include/system/asm/ptrace.h: ... this.
+
+2015-11-24  Maxim Ostapenko  
+
 	* include/system/linux/asm/ptrace.h: New header.
 
 2015-11-23  Maxim Ostapenko  
diff --git a/libsanitizer/include/system/asm/ptrace.h b/libsanitizer/include/system/asm/ptrace.h
new file mode 100644
index 000..5d2fe9b
--- /dev/null
+++ b/libsanitizer/include/system/asm/ptrace.h
@@ -0,0 +1,7 @@
+#include_next 
+/* ARM_VFPREGS_SIZE has been added in 3.0 */
+#if defined(__arm__) && !defined(ARM_VFPREGS_SIZE)
+/* The size of the user-visible VFP state as seen by PTRACE_GET/SETVFPREGS
+   and core dumps.  */
+#define ARM_VFPREGS_SIZE ( 32 * 8 /*fpregs*/ + 4 /*fpscr*/ )
+#endif
diff --git a/libsanitizer/include/system/linux/asm/ptrace.h b/libsanitizer/include/system/linux/asm/ptrace.h
deleted file mode 100644
index d4249fe..000
--- a/libsanitizer/include/system/linux/asm/ptrace.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#include_next 
-/* ARM_VFPREGS_SIZE has been added in 3.0 */
-#if defined(__arm__) && !defined(ARM_VFPREGS_SIZE)
-/* The size of the user-visible VFP state as seen by PTRACE_GET/SETVFPREGS
-   and core dumps.  */
-#define ARM_VFPREGS_SIZE ( 32 * 8 /*fpregs*/ + 4 /*fpscr*/ )
-#endif


Re: [PATCH 1/2] Libsanitizer merge from upstream r253555.

2015-11-24 Thread Maxim Ostapenko

On 24/11/15 15:17, Christophe Lyon wrote:

On 24 November 2015 at 12:57, Jakub Jelinek  wrote:

On Tue, Nov 24, 2015 at 02:55:26PM +0300, Maxim Ostapenko wrote:

diff --git a/libsanitizer/ChangeLog b/libsanitizer/ChangeLog
index c392c57..895d3bd 100644
--- a/libsanitizer/ChangeLog
+++ b/libsanitizer/ChangeLog
@@ -1,5 +1,10 @@
  2015-11-24  Maxim Ostapenko  

+ * include/system/linux/asm/ptrace.h: Move to ...
+ * include/system/asm/ptrace.h: ... this.
+
+2015-11-24  Maxim Ostapenko  
+
   * include/system/linux/asm/ptrace.h: New header.

Of course, sorry for not catching that.


Indeed, this works. Thanks.


 Jakub


Applied as r230804, sorry for inconvenience!

-Maxim


[PING][PATCH][4.9] Backport fix for PR sanitizer/64820.

2015-11-25 Thread Maxim Ostapenko
I would like to ping the patch: 
https://gcc.gnu.org/ml/gcc-patches/2015-11/msg02174.html.




[PING v2][PATCH][4.9] Backport fix for PR sanitizer/64820.

2015-12-01 Thread Maxim Ostapenko

On 25/11/15 12:14, Maxim Ostapenko wrote:
I would like to ping the patch: 
https://gcc.gnu.org/ml/gcc-patches/2015-11/msg02174.html.




Ping.

-Maxim


[PING v3][PATCH][4.9] Backport fix for PR sanitizer/64820.

2015-12-08 Thread Maxim Ostapenko


On 01/12/15 20:23, Maxim Ostapenko wrote:

On 25/11/15 12:14, Maxim Ostapenko wrote:
I would like to ping the patch: 
https://gcc.gnu.org/ml/gcc-patches/2015-11/msg02174.html.




Ping.



Ping.

-Maxim



[PING^3][RFC, PATCH][ASAN] Implement dynamic allocas/VLAs sanitization.​

2017-06-13 Thread Maxim Ostapenko

Hi,

I would like to ping the following patch: 
https://gcc.gnu.org/ml/gcc-patches/2017-05/msg01374.html

Rebased version is attached.

Thanks,
-Maxim
gcc/ChangeLog:

2017-06-13  Maxim Ostapenko  

	* asan.c: Include gimple-fold.h.
	(get_last_alloca_addr): New function.
	(handle_builtin_stackrestore): Likewise.
	(handle_builtin_alloca): Likewise.
	(asan_emit_allocas_unpoison): Likewise.
	(get_mem_refs_of_builtin_call): Add new parameter, remove const
	quallifier from first paramerer. Handle BUILT_IN_ALLOCA,
	BUILT_IN_ALLOCA_WITH_ALIGN and BUILT_IN_STACK_RESTORE builtins.
	(instrument_builtin_call): Pass gimple iterator to
	get_mem_refs_of_builtin_call.
	(last_alloca_addr): New global.
	* asan.h (asan_emit_allocas_unpoison): Declare.
	* builtins.c (expand_asan_emit_allocas_unpoison): New function.
	(expand_builtin): Handle BUILT_IN_ASAN_ALLOCAS_UNPOISON.
	* cfgexpand.c (expand_used_vars): Call asan_emit_allocas_unpoison
	if function calls alloca.
	* gimple-fold.c (replace_call_with_value): Remove static keyword.
	* gimple-fold.h (replace_call_with_value): Declare.
	* internal-fn.c: Include asan.h.
	* sanitizer.def (BUILT_IN_ASAN_ALLOCA_POISON,
	BUILT_IN_ASAN_ALLOCAS_UNPOISON): New builtins.

gcc/testsuite/ChangeLog:

2017-06-13  Maxim Ostapenko  

	* c-c++-common/asan/alloca_big_alignment.c: New test.
	* c-c++-common/asan/alloca_detect_custom_size.c: Likewise.
	* c-c++-common/asan/alloca_instruments_all_paddings.c: Likewise.
	* c-c++-common/asan/alloca_loop_unpoisoning.c: Likewise.
	* c-c++-common/asan/alloca_overflow_partial.c: Likewise.
	* c-c++-common/asan/alloca_overflow_right.c: Likewise.
	* c-c++-common/asan/alloca_safe_access.c: Likewise.
	* c-c++-common/asan/alloca_underflow_left.c: Likewise.

diff --git a/gcc/asan.c b/gcc/asan.c
index bf564a4..4835db9 100644
--- a/gcc/asan.c
+++ b/gcc/asan.c
@@ -55,6 +55,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "langhooks.h"
 #include "cfgloop.h"
 #include "gimple-builder.h"
+#include "gimple-fold.h"
 #include "ubsan.h"
 #include "params.h"
 #include "builtins.h"
@@ -245,6 +246,7 @@ along with GCC; see the file COPYING3.  If not see
 static unsigned HOST_WIDE_INT asan_shadow_offset_value;
 static bool asan_shadow_offset_computed;
 static vec sanitized_sections;
+static tree last_alloca_addr = NULL_TREE;
 
 /* Set of variable declarations that are going to be guarded by
use-after-scope sanitizer.  */
@@ -531,11 +533,166 @@ get_mem_ref_of_assignment (const gassign *assignment,
   return true;
 }
 
+/* Return address of last allocated dynamic alloca.  */
+
+static tree
+get_last_alloca_addr ()
+{
+  if (last_alloca_addr)
+return last_alloca_addr;
+
+  gimple_seq seq = NULL;
+  gassign *g;
+
+  last_alloca_addr = create_tmp_reg (ptr_type_node, "last_alloca_addr");
+  g = gimple_build_assign (last_alloca_addr, NOP_EXPR,
+			   build_int_cst (ptr_type_node, 0));
+  gimple_seq_add_stmt_without_update (&seq, g);
+
+  edge e = single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun));
+  gsi_insert_seq_on_edge_immediate (e, seq);
+  return last_alloca_addr;
+}
+
+/* Insert __asan_allocas_unpoison(top, bottom) call after
+   __builtin_stackrestore(new_sp) call.
+   The pseudocode of this routine should look like this:
+ __builtin_stackrestore(new_sp);
+ top = last_alloca_addr;
+ bot = virtual_dynamic_stack_rtx;
+ __asan_allocas_unpoison(top, bottom);
+ last_alloca_addr = new_sp;
+   We don't use new_sp as bot parameter because on some architectures
+   SP has non zero offset from dynamic stack area.  Moreover, on some
+   architectures this offset (STACK_DYNAMIC_OFFSET) becomes known for each
+   particular function only after all callees were expanded to rtl.
+   The most noticable example is PowerPC{,64}, see
+   http://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi.html#DYNAM-STACK.
+*/
+
+static void
+handle_builtin_stackrestore (gcall *call, gimple_stmt_iterator *iter)
+{
+  if (!iter)
+return;
+
+  gimple_stmt_iterator gsi = *iter;
+  gimple_seq seq = NULL;
+  tree last_alloca_addr = get_last_alloca_addr ();
+  tree restored_stack = gimple_call_arg (call, 0);
+  tree fn = builtin_decl_implicit (BUILT_IN_ASAN_ALLOCAS_UNPOISON);
+  gimple *g = gimple_build_call (fn, 2, last_alloca_addr, restored_stack);
+  gimple_seq_add_stmt_without_update (&seq, g);
+  g = gimple_build_assign (last_alloca_addr, NOP_EXPR, restored_stack);
+  gimple_seq_add_stmt_without_update (&seq, g);
+  gsi_insert_seq_after (&gsi, seq, GSI_SAME_STMT);
+}
+
+/* Deploy and poison redzones around __builtin_alloca call.  To do this, we
+   should replace this call with another one with changed parameters and
+   replace all its uses with new address, so
+ addr = __builtin_alloca (old_size, align);
+   is replaced by
+ new_size = old_size + additional_size;
+ tmp = __builtin_alloca (new_size, max(align, 32))
+ addr = tmp + 32 (first 3

Re: [PING^3][RFC, PATCH][ASAN] Implement dynamic allocas/VLAs sanitization.​

2017-06-14 Thread Maxim Ostapenko

Hi Jakub,

thank you for your points. I've updated the patch.

-Maxim


gcc/ChangeLog:

2017-06-14  Maxim Ostapenko  

	* asan.c: Include gimple-fold.h.
	(get_last_alloca_addr): New function.
	(handle_builtin_stackrestore): Likewise.
	(handle_builtin_alloca): Likewise.
	(asan_emit_allocas_unpoison): Likewise.
	(get_mem_refs_of_builtin_call): Add new parameter, remove const
	quallifier from first paramerer. Handle BUILT_IN_ALLOCA,
	BUILT_IN_ALLOCA_WITH_ALIGN and BUILT_IN_STACK_RESTORE builtins.
	(instrument_builtin_call): Pass gimple iterator to
	get_mem_refs_of_builtin_call.
	(last_alloca_addr): New global.
	* asan.h (asan_emit_allocas_unpoison): Declare.
	* builtins.c (expand_asan_emit_allocas_unpoison): New function.
	(expand_builtin): Handle BUILT_IN_ASAN_ALLOCAS_UNPOISON.
	* cfgexpand.c (expand_used_vars): Call asan_emit_allocas_unpoison
	if function calls alloca.
	* gimple-fold.c (replace_call_with_value): Remove static keyword.
	* gimple-fold.h (replace_call_with_value): Declare.
	* internal-fn.c: Include asan.h.
	* sanitizer.def (BUILT_IN_ASAN_ALLOCA_POISON,
	BUILT_IN_ASAN_ALLOCAS_UNPOISON): New builtins.

gcc/testsuite/ChangeLog:

2017-06-14  Maxim Ostapenko  

	* c-c++-common/asan/alloca_big_alignment.c: New test.
	* c-c++-common/asan/alloca_detect_custom_size.c: Likewise.
	* c-c++-common/asan/alloca_instruments_all_paddings.c: Likewise.
	* c-c++-common/asan/alloca_loop_unpoisoning.c: Likewise.
	* c-c++-common/asan/alloca_overflow_partial.c: Likewise.
	* c-c++-common/asan/alloca_overflow_right.c: Likewise.
	* c-c++-common/asan/alloca_safe_access.c: Likewise.
	* c-c++-common/asan/alloca_underflow_left.c: Likewise.

diff --git a/gcc/asan.c b/gcc/asan.c
index bf564a4..28e773a 100644
--- a/gcc/asan.c
+++ b/gcc/asan.c
@@ -55,6 +55,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "langhooks.h"
 #include "cfgloop.h"
 #include "gimple-builder.h"
+#include "gimple-fold.h"
 #include "ubsan.h"
 #include "params.h"
 #include "builtins.h"
@@ -245,6 +246,7 @@ along with GCC; see the file COPYING3.  If not see
 static unsigned HOST_WIDE_INT asan_shadow_offset_value;
 static bool asan_shadow_offset_computed;
 static vec sanitized_sections;
+static tree last_alloca_addr = NULL_TREE;
 
 /* Set of variable declarations that are going to be guarded by
use-after-scope sanitizer.  */
@@ -531,11 +533,166 @@ get_mem_ref_of_assignment (const gassign *assignment,
   return true;
 }
 
+/* Return address of last allocated dynamic alloca.  */
+
+static tree
+get_last_alloca_addr ()
+{
+  if (last_alloca_addr)
+return last_alloca_addr;
+
+  gimple_seq seq = NULL;
+  gassign *g;
+
+  last_alloca_addr = create_tmp_reg (ptr_type_node, "last_alloca_addr");
+  g = gimple_build_assign (last_alloca_addr, NOP_EXPR,
+			   build_int_cst (ptr_type_node, 0));
+  gimple_seq_add_stmt_without_update (&seq, g);
+
+  edge e = single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun));
+  gsi_insert_seq_on_edge_immediate (e, seq);
+  return last_alloca_addr;
+}
+
+/* Insert __asan_allocas_unpoison (top, bottom) call after
+   __builtin_stack_restore (new_sp) call.
+   The pseudocode of this routine should look like this:
+ __builtin_stack_restore (new_sp);
+ top = last_alloca_addr;
+ bot = virtual_dynamic_stack_rtx;
+ __asan_allocas_unpoison (top, bottom);
+ last_alloca_addr = new_sp;
+   We don't use new_sp as bot parameter because on some architectures
+   SP has non zero offset from dynamic stack area.  Moreover, on some
+   architectures this offset (STACK_DYNAMIC_OFFSET) becomes known for each
+   particular function only after all callees were expanded to rtl.
+   The most noticable example is PowerPC{,64}, see
+   http://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi.html#DYNAM-STACK.
+*/
+
+static void
+handle_builtin_stack_restore (gcall *call, gimple_stmt_iterator *iter)
+{
+  if (!iter)
+return;
+
+  gimple_stmt_iterator gsi = *iter;
+  gimple_seq seq = NULL;
+  tree last_alloca_addr = get_last_alloca_addr ();
+  tree restored_stack = gimple_call_arg (call, 0);
+  tree fn = builtin_decl_implicit (BUILT_IN_ASAN_ALLOCAS_UNPOISON);
+  gimple *g = gimple_build_call (fn, 2, last_alloca_addr, restored_stack);
+  gimple_seq_add_stmt_without_update (&seq, g);
+  g = gimple_build_assign (last_alloca_addr, NOP_EXPR, restored_stack);
+  gimple_seq_add_stmt_without_update (&seq, g);
+  gsi_insert_seq_after (&gsi, seq, GSI_SAME_STMT);
+}
+
+/* Deploy and poison redzones around __builtin_alloca call.  To do this, we
+   should replace this call with another one with changed parameters and
+   replace all its uses with new address, so
+ addr = __builtin_alloca (old_size, align);
+   is replaced by
+ new_size = old_size + additional_size;
+ tmp = __builtin_alloca (new_size, max (align, 32))
+ addr = tmp + 32 (first 32 bytes are for the left redzone);
+   ADDITIONAL_SIZE is added to m

[PATCH, Committed] Add myself to MAINTAINERS file

2017-06-26 Thread Maxim Ostapenko

Hi,

when requesting cfarm account, Segher noticed that I didn't add myself 
in MAINTAINERS file when obtained write access to SVN repo. Fixing this now.


-Maxim
diff --git a/MAINTAINERS b/MAINTAINERS
index c76c181..04fcb8a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -523,6 +523,7 @@ Braden Obrzut	
 Carlos O'Donell	
 Peter O'Gorman	
 Andrea Ornstein	
+Maxim Ostapenko	
 Patrick Palka	
 Devang Patel	
 Andris Pavenis	


[PATCH v2][ASAN] Implement dynamic allocas/VLAs sanitization.​

2017-06-26 Thread Maxim Ostapenko

Hi,

I'm sorry for a long delay. Here an updated patch.
Following Jakub's suggestion from previous review, I've added a 
get_nonzero_bits stuff into handle_builtin_alloca in order to avoid 
redundant redzone size calculations in case we know that alloca has 
alignment >= ASAN_RED_ZONE_SIZE. Thus, for the following code:


struct __attribute__((aligned (N))) S { char s[N]; };

void bar (struct S *, struct S *);

void
foo (int x)
{
  struct S a;
  {
struct S b[x];
bar (&a, &b[0]);
  }
  {
struct S b[x + 4];
bar (&a, &b[0]);
  }
}

void
baz (int x)
{
  struct S a;
  struct S b[x];
  bar (&a, &b[0]);
}

compiled with -O2 -fsanitize=address -DN=64, we have expected

  _2 = (sizetype) x_1(D);
  _8 = _2 * 64;
  _14 = _8 + 96;
  _15 = __builtin_alloca_with_align (_14, 512);
  _16 = _15 + 64;
  __builtin___asan_alloca_poison (_16, _8);

instead of previous

  _1 = (sizetype) x_4(D);
  _2 = _1 * 64;
  _24 = _2 & 31;
  _19 = _2 + 128;
  _27 = _19 - _24;
  _28 = __builtin_alloca_with_align (_27, 512);
  _29 = _28 + 64;
  __builtin___asan_alloca_poison (_29, _2);


Also, I've added a simple pattern for X & C -> 0 if we know that corresponding 
bits are zero, but I'm not sure this pattern has a practical value.
Tested and bootstrapped on x86_64-unknown-linux-gnu. Could you take a look?

-Maxim

gcc/ChangeLog:

2017-06-26  Maxim Ostapenko  

	* asan.c: Include gimple-fold.h.
	(get_last_alloca_addr): New function.
	(handle_builtin_stackrestore): Likewise.
	(handle_builtin_alloca): Likewise.
	(asan_emit_allocas_unpoison): Likewise.
	(get_mem_refs_of_builtin_call): Add new parameter, remove const
	quallifier from first paramerer. Handle BUILT_IN_ALLOCA,
	BUILT_IN_ALLOCA_WITH_ALIGN and BUILT_IN_STACK_RESTORE builtins.
	(instrument_builtin_call): Pass gimple iterator to
	get_mem_refs_of_builtin_call.
	(last_alloca_addr): New global.
	* asan.h (asan_emit_allocas_unpoison): Declare.
	* builtins.c (expand_asan_emit_allocas_unpoison): New function.
	(expand_builtin): Handle BUILT_IN_ASAN_ALLOCAS_UNPOISON.
	* cfgexpand.c (expand_used_vars): Call asan_emit_allocas_unpoison
	if function calls alloca.
	* gimple-fold.c (replace_call_with_value): Remove static keyword.
	* gimple-fold.h (replace_call_with_value): Declare.
	* internal-fn.c: Include asan.h.
	* sanitizer.def (BUILT_IN_ASAN_ALLOCA_POISON,
	BUILT_IN_ASAN_ALLOCAS_UNPOISON): New builtins.
	* match.pd: Add new pattern.

gcc/testsuite/ChangeLog:

2017-06-26  Maxim Ostapenko  

	* c-c++-common/asan/alloca_big_alignment.c: New test.
	* c-c++-common/asan/alloca_detect_custom_size.c: Likewise.
	* c-c++-common/asan/alloca_instruments_all_paddings.c: Likewise.
	* c-c++-common/asan/alloca_loop_unpoisoning.c: Likewise.
	* c-c++-common/asan/alloca_overflow_partial.c: Likewise.
	* c-c++-common/asan/alloca_overflow_right.c: Likewise.
	* c-c++-common/asan/alloca_safe_access.c: Likewise.
	* c-c++-common/asan/alloca_underflow_left.c: Likewise.

diff --git a/gcc/asan.c b/gcc/asan.c
index e730530..6d7a5ec 100644
--- a/gcc/asan.c
+++ b/gcc/asan.c
@@ -55,6 +55,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "langhooks.h"
 #include "cfgloop.h"
 #include "gimple-builder.h"
+#include "gimple-fold.h"
 #include "ubsan.h"
 #include "params.h"
 #include "builtins.h"
@@ -245,6 +246,7 @@ along with GCC; see the file COPYING3.  If not see
 static unsigned HOST_WIDE_INT asan_shadow_offset_value;
 static bool asan_shadow_offset_computed;
 static vec sanitized_sections;
+static tree last_alloca_addr = NULL_TREE;
 
 /* Set of variable declarations that are going to be guarded by
use-after-scope sanitizer.  */
@@ -529,11 +531,183 @@ get_mem_ref_of_assignment (const gassign *assignment,
   return true;
 }
 
+/* Return address of last allocated dynamic alloca.  */
+
+static tree
+get_last_alloca_addr ()
+{
+  if (last_alloca_addr)
+return last_alloca_addr;
+
+  gimple_seq seq = NULL;
+  gassign *g;
+
+  last_alloca_addr = create_tmp_reg (ptr_type_node, "last_alloca_addr");
+  g = gimple_build_assign (last_alloca_addr, NOP_EXPR,
+			   build_int_cst (ptr_type_node, 0));
+  gimple_seq_add_stmt_without_update (&seq, g);
+
+  edge e = single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun));
+  gsi_insert_seq_on_edge_immediate (e, seq);
+  return last_alloca_addr;
+}
+
+/* Insert __asan_allocas_unpoison (top, bottom) call after
+   __builtin_stack_restore (new_sp) call.
+   The pseudocode of this routine should look like this:
+ __builtin_stack_restore (new_sp);
+ top = last_alloca_addr;
+ bot = virtual_dynamic_stack_rtx;
+ __asan_allocas_unpoison (top, bottom);
+ last_alloca_addr = new_sp;
+   We don't use new_sp as bot parameter because on some architectures
+   SP has non zero offset from dynamic stack area.  Moreover, on some
+   architectures this offset (STACK_DYNAMIC_OFFSET) becomes known for each
+   part

Re: [PATCH v2][ASAN] Implement dynamic allocas/VLAs sanitization.​

2017-06-30 Thread Maxim Ostapenko

Hi,

On 29/06/17 15:35, Jakub Jelinek wrote:

Hi!

Sorry for the review delay.

On Mon, Jun 26, 2017 at 03:49:23PM +0300, Maxim Ostapenko wrote:

(handle_builtin_stackrestore): Likewise.

The function is called with _ between stack and restore.


* match.pd: Add new pattern.

Unless the patch relies on this, I think it should be posted separately
and reviewed by Richard.


OK, good point, will remove from this patch.




@@ -245,6 +246,7 @@ along with GCC; see the file COPYING3.  If not see
  static unsigned HOST_WIDE_INT asan_shadow_offset_value;
  static bool asan_shadow_offset_computed;
  static vec sanitized_sections;
+static tree last_alloca_addr = NULL_TREE;

You are shadowing this variable in multiple places.  Either rename it to
something different, or rename the results of get_last_alloca_addr.
And the " = NULL_TREE" part is not needed.


Err, thanks, will fix it.



  
  /* Set of variable declarations that are going to be guarded by

 use-after-scope sanitizer.  */
@@ -529,11 +531,183 @@ get_mem_ref_of_assignment (const gassign *assignment,
return true;
  }
  
+/* Return address of last allocated dynamic alloca.  */

+
+static tree
+get_last_alloca_addr ()
+{
+  if (last_alloca_addr)
+return last_alloca_addr;
+
+  gimple_seq seq = NULL;
+  gassign *g;
+
+  last_alloca_addr = create_tmp_reg (ptr_type_node, "last_alloca_addr");
+  g = gimple_build_assign (last_alloca_addr, NOP_EXPR,
+  build_int_cst (ptr_type_node, 0));

Instead of build_int_cst (ptr_type_node, 0) you should use
null_pointer_node.  And the NOP_EXPR there is just wrong, either it
should be gimple_build_assign (last_alloca_addr, null_pointer_node);
or gimple_build_assign (last_alloca_addr, INTEGER_CST, null_pointer_node);


+  gimple_seq_add_stmt_without_update (&seq, g);

Why the seq stuff at all?  You have a single stmt you want to insert on
edge.


Right, will fix it.


+
+  edge e = single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun));
+  gsi_insert_seq_on_edge_immediate (e, seq);

So just use here
   gsi_insert_on_edge_immediate (e, g);
instead.


+  return last_alloca_addr;
+}
+
+/* Insert __asan_allocas_unpoison (top, bottom) call after
+   __builtin_stack_restore (new_sp) call.
+   The pseudocode of this routine should look like this:
+ __builtin_stack_restore (new_sp);
+ top = last_alloca_addr;
+ bot = virtual_dynamic_stack_rtx;
+ __asan_allocas_unpoison (top, bottom);
+ last_alloca_addr = new_sp;

The comment doesn't seem to agree with what you actually implement.
There is no virtual_dynamic_stack_rtx during the asan pass, it is there
only during expansion until the virtual regs are instantiated in the next
pass.  Furthermore, you have bot variable, but then use bottom.


Right, 'bottom' should be replaced by 'bot'.
Regarding to virtual_dynamic_stactk_rtx - as you correctly noted below, 
second parameter of __asan_allocas_unpoison will be completely rewritten 
in expand_builtin_alloca function by virtual_dynamic_stactk_rtx. Here 
I've just passed new_sp as a dummy argument. This looks hacky, but the 
problem is that for several architectures (e.g. PPC) we cannot use 
new_sp as a 'bot' parameter because new_sp != last_alloca_addr on these 
targets. Originally, I tried to do something like this:


  top = last_alloca_addr;
  bot = new_sp + STACK_DYNAMIC_OFFSET;
  __asan_allocas_unpoison(top, bot);
  last_alloca_addr = bot;

but I was confused by the fact that STACK_DYNAMIC_OFFSET becomes 
available only after expansion to RTL. Rewriting 'bot' with 
virtual_dynamic_stactk_rtx in RTL looks like the most feasible way how 
to overcome this issue for me.





+  tree last_alloca_addr = get_last_alloca_addr ();

Here is the shadowing I talked about.


+  tree restored_stack = gimple_call_arg (call, 0);
+  tree fn = builtin_decl_implicit (BUILT_IN_ASAN_ALLOCAS_UNPOISON);
+  gimple *g = gimple_build_call (fn, 2, last_alloca_addr, restored_stack);

Here you clearly use the first argument of __builtin_stack_restore, which
is that new_sp.


+  gimple_seq_add_stmt_without_update (&seq, g);

Why the messing up with sequences?  Just insert the stmt immediately in,
and the others as well.


+  g = gimple_build_assign (last_alloca_addr, NOP_EXPR, restored_stack);

This is again wrong, here you really don't know what restored_stack is,
it could be SSA_NAME, but also something different, so you should use
gimple_build_assign (last_alloca_addr, restored_stack);
and let it figure out the rhs code.


Thanks, will fix.




+  /* Extract lower bits from old_size.  */
+  wide_int size_nonzero_bits = get_nonzero_bits (old_size);
+  wide_int rz_mask
+= wi::uhwi (redzone_mask, wi::get_precision (size_nonzero_bits));
+  wide_int old_size_lower_bits = wi::bit_and (size_nonzero_bits, rz_mask);
+
+  /* If alloca size is aligned to ASAN_RED_ZONE_SIZE, we don't need partial
+

[Ping][PATCH v2] Fix Incorrect ASan global variables alignment on arm (PR sanitizer/81697)

2017-11-12 Thread Maxim Ostapenko

Hi,

I would like to ping the following patch:
https://gcc.gnu.org/ml/gcc-patches/2017-10/msg02288.html

Thanks,
-Maxim
gcc/ChangeLog:

2017-11-13  Maxim Ostapenko  

	PR sanitizer/81697
	* asan.c (asan_protect_global): Add new ignore_decl_rtl_set_p
	parameter. Return true if ignore_decl_rtl_set_p is true and other
	conditions are satisfied.
	* asan.h (asan_protect_global): Add new parameter.
	* varasm.c (categorize_decl_for_section): Pass true as second parameter
	to asan_protect_global calls.

gcc/testsuite/ChangeLog:

2017-11-13  Maxim Ostapenko  

	PR sanitizer/81697
	* g++.dg/asan/global-alignment.C: New test.

diff --git a/gcc/asan.c b/gcc/asan.c
index d5128aa..78c3b60 100644
--- a/gcc/asan.c
+++ b/gcc/asan.c
@@ -1605,7 +1605,7 @@ is_odr_indicator (tree decl)
ASAN_RED_ZONE_SIZE bytes.  */
 
 bool
-asan_protect_global (tree decl)
+asan_protect_global (tree decl, bool ignore_decl_rtl_set_p)
 {
   if (!ASAN_GLOBALS)
 return false;
@@ -1627,7 +1627,13 @@ asan_protect_global (tree decl)
   || DECL_THREAD_LOCAL_P (decl)
   /* Externs will be protected elsewhere.  */
   || DECL_EXTERNAL (decl)
-  || !DECL_RTL_SET_P (decl)
+  /* PR sanitizer/81697: For architectures that use section anchors first
+	 call to asan_protect_global may occur before DECL_RTL (decl) is set.
+	 We should ignore DECL_RTL_SET_P then, because otherwise the first call
+	 to asan_protect_global will return FALSE and the following calls on the
+	 same decl after setting DECL_RTL (decl) will return TRUE and we'll end
+	 up with inconsistency at runtime.  */
+  || (!DECL_RTL_SET_P (decl) && !ignore_decl_rtl_set_p)
   /* Comdat vars pose an ABI problem, we can't know if
 	 the var that is selected by the linker will have
 	 padding or not.  */
@@ -1651,6 +1657,9 @@ asan_protect_global (tree decl)
   || is_odr_indicator (decl))
 return false;
 
+  if (ignore_decl_rtl_set_p)
+return true;
+
   rtl = DECL_RTL (decl);
   if (!MEM_P (rtl) || GET_CODE (XEXP (rtl, 0)) != SYMBOL_REF)
 return false;
diff --git a/gcc/asan.h b/gcc/asan.h
index c82d4d9..885b47e 100644
--- a/gcc/asan.h
+++ b/gcc/asan.h
@@ -26,7 +26,7 @@ extern void asan_finish_file (void);
 extern rtx_insn *asan_emit_stack_protection (rtx, rtx, unsigned int,
 	 HOST_WIDE_INT *, tree *, int);
 extern rtx_insn *asan_emit_allocas_unpoison (rtx, rtx, rtx_insn *);
-extern bool asan_protect_global (tree);
+extern bool asan_protect_global (tree, bool ignore_decl_rtl_set_p = false);
 extern void initialize_sanitizer_builtins (void);
 extern tree asan_dynamic_init_call (bool);
 extern bool asan_expand_check_ifn (gimple_stmt_iterator *, bool);
diff --git a/gcc/testsuite/g++.dg/asan/global-alignment.C b/gcc/testsuite/g++.dg/asan/global-alignment.C
new file mode 100644
index 000..84dac37
--- /dev/null
+++ b/gcc/testsuite/g++.dg/asan/global-alignment.C
@@ -0,0 +1,18 @@
+/* { dg-options "-fmerge-all-constants" } */
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } { "" } } */
+
+#include 
+#include 
+
+const char kRecoveryInstallString[] = "NEW";
+const char kRecoveryUpdateString[] = "UPDATE";
+const char kRecoveryUninstallationString[] = "UNINSTALL";
+
+const std::map kStringToRequestMap = {
+  {kRecoveryInstallString, 0},
+  {kRecoveryUpdateString, 0},
+  {kRecoveryUninstallationString, 0},
+};
+
+/* { dg-final { scan-assembler-times {\.section\s+\.rodata\n(?:(?!\.section).)*\.\w+\s+"NEW} 1 } } */
diff --git a/gcc/varasm.c b/gcc/varasm.c
index a139151..849eae0 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -6508,7 +6508,7 @@ categorize_decl_for_section (const_tree decl, int reloc)
   else if (TREE_CODE (decl) == STRING_CST)
 {
   if ((flag_sanitize & SANITIZE_ADDRESS)
-	  && asan_protect_global (CONST_CAST_TREE (decl)))
+	  && asan_protect_global (CONST_CAST_TREE (decl), true))
   /* or !flag_merge_constants */
 return SECCAT_RODATA;
   else
@@ -6536,7 +6536,7 @@ categorize_decl_for_section (const_tree decl, int reloc)
 	ret = reloc == 1 ? SECCAT_DATA_REL_RO_LOCAL : SECCAT_DATA_REL_RO;
   else if (reloc || flag_merge_constants < 2
 	   || ((flag_sanitize & SANITIZE_ADDRESS)
-		   && asan_protect_global (CONST_CAST_TREE (decl
+		   && asan_protect_global (CONST_CAST_TREE (decl), true)))
 	/* C and C++ don't allow different variables to share the same
 	   location.  -fmerge-all-constants allows even that (at the
 	   expense of not conforming).  */


Re: [RFC PATCH] Merge libsanitizer from upstream

2017-11-14 Thread Maxim Ostapenko

Hi,

On 13/11/17 15:47, Christophe Lyon wrote:

On 30 October 2017 at 16:21, Maxim Ostapenko  wrote:

On 30/10/17 17:08, Christophe Lyon wrote:

On 30/10/2017 11:12, Maxim Ostapenko wrote:

Hi,

sorry for the late response.

On 20/10/17 13:45, Christophe Lyon wrote:

Hi,

On 19 October 2017 at 13:17, Jakub Jelinek  wrote:

On Thu, Oct 19, 2017 at 02:07:24PM +0300, Maxim Ostapenko wrote:

Is the patch (the merge + this incremental) ok for trunk?

I think the patch is OK, just wondering about two things:

Richi just approved the patch on IRC, so I'll commit, then we can deal
with
follow-ups.


Does anyone else run these tests on arm?
Since you applied this patch, I'm seeing lots of new errors and
timeouts.
I have been ignoring regression reports for *san because of yyrandomness
in the results, but the timeouts are a  major inconvenience in testing
because it increases latency a lot in getting results, or worse I get no
result at all because the validation job is killed before completion.

Looking at some intermediate logs, I have noticed:
==24797==AddressSanitizer CHECK failed:
/libsanitizer/asan/asan_poisoning.cc:34
"((AddrIsAlignedByGranularity(addr))) != (0)" (0x0, 0x0)
  #0 0x408d7d65 in AsanCheckFailed /libsanitizer/asan/asan_rtl.cc:67
  #1 0x408ecd5d in __sanitizer::CheckFailed(char const*, int, char
const*, unsigned long long, unsigned long long)
/libsanitizer/sanitizer_common/sanitizer_termination.cc:77
  #2 0x408d22d5 in __asan::PoisonShadow(unsigned long, unsigned
long, unsigned char) /libsanitizer/asan/asan_poisoning.cc:34
  #3 0x4085409b in __asan_register_globals
/libsanitizer/asan/asan_globals.cc:368
  #4 0x109eb in _GLOBAL__sub_I_00099_1_ten

(/aci-gcc-fsf/builds/gcc-fsf-gccsrc-thumb/obj-arm-none-linux-gnueabi/gcc3/gcc/testsuite/gcc/alloca_big_alignment.exe+0x109eb)

in MANY (193 in gcc) tests.

and many others (152 in gcc) just time out individually (eg
c-c++-common/asan/alloca_instruments_all_paddings.c) with no error in
the logs besides Dejagnu's
WARNING: program timed out.


Since I'm using an apparently unusual setup, maybe I have to update it
to cope with the new version,
so I'd like to know if others are seeing the same problems on arm?

I'm using qemu -R 0 to execute the test programs, encapsulated by
proot (similar to chroot, but does not require root privileges).

Am I missing something obvious?


I've caught the same error on my Arndale board. The issue seems to be
quite obvious: after merge, ASan requires globals array to be aligned by
shadow granularity.


Thanks for confirming. I've spent a lot of time investigating the timeout
issues, that led to zombie processes and servers needing reboot. I've
finally identified that going back to qemu-2.7 avoid the timeout issues
(I've reported a qemu bug).


This trivial patch seems to fix the issue. Could you check it on your
setup?


I was just about to finally start looking at this sanity check problem, so
thank you very much for sharing your patch.
I manually tested it on the subset of my configs and it solves the
assertion failure, thanks!
However, I can notice many regressions compared to before the merge:
c-c++-common/asan/alloca_instruments_all_paddings.c
c-c++-common/asan/alloca_loop_unpoisoning.c
c-c++-common/asan/alloca_safe_access.c
c-c++-common/asan/asan-interface-1.c
c-c++-common/asan/halt_on_error-1.c
c-c++-common/asan/pr59063-1.c
c-c++-common/asan/pr59063-2.c
c-c++-common/asan/pr63316.c
c-c++-common/asan/pr63888.c
c-c++-common/asan/pr70712.c
c-c++-common/asan/pr71480.c
c-c++-common/asan/pr79944.c
c-c++-common/asan/pr80308.c
c-c++-common/asan/swapcontext-test-1.c
gcc.dg/asan/nosanitize-and-inline.c
gcc.dg/asan/pr79196.c
gcc.dg/asan/pr80166.c
gcc.dg/asan/pr81186.c
gcc.dg/asan/use-after-scope-11.c
gcc.dg/asan/use-after-scope-4.c
gcc.dg/asan/use-after-scope-6.c
gcc.dg/asan/use-after-scope-7.c
gcc.dg/asan/use-after-scope-goto-1.c
gcc.dg/asan/use-after-scope-goto-2.c
gcc.dg/asan/use-after-scope-switch-1.c
gcc.dg/asan/use-after-scope-switch-2.c
gcc.dg/asan/use-after-scope-switch-3.c
gcc.dg/asan/use-after-scope-switch-4.c

out of which only
c-c++-common/asan/swapcontext-test-1.c
c-c++-common/asan/halt_on_error-1.c
print something in gcc.log

Do they pass for you?


Ah, I see. The problem is that after this merge LSan was enabled for ARM.
LSan sets atexit handler that calls internal_clone function that's not
supported in QEMU.
That's why these tests pass on board, but fail under QEMU.
Could you try set ASAN_OPTIONS=detect_leaks=0 in your environment?


Hi,

I have a followup on this issue, after investigating a bit more.

I filed a bug report against QEMU, and indeed it seems that it rejects
clone() as called by the sanitizers on purpose, because it cannot support
CLONE_UNTRACED.

That being said, I was wondering why the same tests worked "better"
with qemu-aarch64 (as opposed to qemu-arm). And I noticed that on aarch64,
we have san

Re: [RFC PATCH] Merge libsanitizer from upstream

2017-11-16 Thread Maxim Ostapenko

Hi Christophe,

On 13/11/17 15:47, Christophe Lyon wrote:

On 30 October 2017 at 16:21, Maxim Ostapenko  wrote:

On 30/10/17 17:08, Christophe Lyon wrote:

On 30/10/2017 11:12, Maxim Ostapenko wrote:

Hi,

sorry for the late response.

On 20/10/17 13:45, Christophe Lyon wrote:

Hi,

On 19 October 2017 at 13:17, Jakub Jelinek  wrote:

On Thu, Oct 19, 2017 at 02:07:24PM +0300, Maxim Ostapenko wrote:

Is the patch (the merge + this incremental) ok for trunk?

I think the patch is OK, just wondering about two things:

Richi just approved the patch on IRC, so I'll commit, then we can deal
with
follow-ups.


Does anyone else run these tests on arm?
Since you applied this patch, I'm seeing lots of new errors and
timeouts.
I have been ignoring regression reports for *san because of yyrandomness
in the results, but the timeouts are a  major inconvenience in testing
because it increases latency a lot in getting results, or worse I get no
result at all because the validation job is killed before completion.

Looking at some intermediate logs, I have noticed:
==24797==AddressSanitizer CHECK failed:
/libsanitizer/asan/asan_poisoning.cc:34
"((AddrIsAlignedByGranularity(addr))) != (0)" (0x0, 0x0)
  #0 0x408d7d65 in AsanCheckFailed /libsanitizer/asan/asan_rtl.cc:67
  #1 0x408ecd5d in __sanitizer::CheckFailed(char const*, int, char
const*, unsigned long long, unsigned long long)
/libsanitizer/sanitizer_common/sanitizer_termination.cc:77
  #2 0x408d22d5 in __asan::PoisonShadow(unsigned long, unsigned
long, unsigned char) /libsanitizer/asan/asan_poisoning.cc:34
  #3 0x4085409b in __asan_register_globals
/libsanitizer/asan/asan_globals.cc:368
  #4 0x109eb in _GLOBAL__sub_I_00099_1_ten

(/aci-gcc-fsf/builds/gcc-fsf-gccsrc-thumb/obj-arm-none-linux-gnueabi/gcc3/gcc/testsuite/gcc/alloca_big_alignment.exe+0x109eb)

in MANY (193 in gcc) tests.

and many others (152 in gcc) just time out individually (eg
c-c++-common/asan/alloca_instruments_all_paddings.c) with no error in
the logs besides Dejagnu's
WARNING: program timed out.


Since I'm using an apparently unusual setup, maybe I have to update it
to cope with the new version,
so I'd like to know if others are seeing the same problems on arm?

I'm using qemu -R 0 to execute the test programs, encapsulated by
proot (similar to chroot, but does not require root privileges).

Am I missing something obvious?


I've caught the same error on my Arndale board. The issue seems to be
quite obvious: after merge, ASan requires globals array to be aligned by
shadow granularity.


Thanks for confirming. I've spent a lot of time investigating the timeout
issues, that led to zombie processes and servers needing reboot. I've
finally identified that going back to qemu-2.7 avoid the timeout issues
(I've reported a qemu bug).


This trivial patch seems to fix the issue. Could you check it on your
setup?


I was just about to finally start looking at this sanity check problem, so
thank you very much for sharing your patch.
I manually tested it on the subset of my configs and it solves the
assertion failure, thanks!
However, I can notice many regressions compared to before the merge:
c-c++-common/asan/alloca_instruments_all_paddings.c
c-c++-common/asan/alloca_loop_unpoisoning.c
c-c++-common/asan/alloca_safe_access.c
c-c++-common/asan/asan-interface-1.c
c-c++-common/asan/halt_on_error-1.c
c-c++-common/asan/pr59063-1.c
c-c++-common/asan/pr59063-2.c
c-c++-common/asan/pr63316.c
c-c++-common/asan/pr63888.c
c-c++-common/asan/pr70712.c
c-c++-common/asan/pr71480.c
c-c++-common/asan/pr79944.c
c-c++-common/asan/pr80308.c
c-c++-common/asan/swapcontext-test-1.c
gcc.dg/asan/nosanitize-and-inline.c
gcc.dg/asan/pr79196.c
gcc.dg/asan/pr80166.c
gcc.dg/asan/pr81186.c
gcc.dg/asan/use-after-scope-11.c
gcc.dg/asan/use-after-scope-4.c
gcc.dg/asan/use-after-scope-6.c
gcc.dg/asan/use-after-scope-7.c
gcc.dg/asan/use-after-scope-goto-1.c
gcc.dg/asan/use-after-scope-goto-2.c
gcc.dg/asan/use-after-scope-switch-1.c
gcc.dg/asan/use-after-scope-switch-2.c
gcc.dg/asan/use-after-scope-switch-3.c
gcc.dg/asan/use-after-scope-switch-4.c

out of which only
c-c++-common/asan/swapcontext-test-1.c
c-c++-common/asan/halt_on_error-1.c
print something in gcc.log

Do they pass for you?


Ah, I see. The problem is that after this merge LSan was enabled for ARM.
LSan sets atexit handler that calls internal_clone function that's not
supported in QEMU.
That's why these tests pass on board, but fail under QEMU.
Could you try set ASAN_OPTIONS=detect_leaks=0 in your environment?


Hi,

I have a followup on this issue, after investigating a bit more.

I filed a bug report against QEMU, and indeed it seems that it rejects
clone() as called by the sanitizers on purpose, because it cannot support
CLONE_UNTRACED.

That being said, I was wondering why the same tests worked "better"
with qemu-aarch64 (as opposed to qemu-arm). And I noticed tha

[Ping][PATCH v3] Fix Incorrect ASan global variables alignment on arm (PR sanitizer/81697)

2017-11-21 Thread Maxim Ostapenko

Hi,

I would like to ping the following patch:
https://gcc.gnu.org/ml/gcc-patches/2017-10/msg02288.html

Thanks,
-Maxim
gcc/ChangeLog:

2017-11-21  Maxim Ostapenko  

	PR sanitizer/81697
	* asan.c (asan_protect_global): Add new ignore_decl_rtl_set_p
	parameter. Return true if ignore_decl_rtl_set_p is true and other
	conditions are satisfied.
	* asan.h (asan_protect_global): Add new parameter.
	* varasm.c (categorize_decl_for_section): Pass true as second parameter
	to asan_protect_global calls.

gcc/testsuite/ChangeLog:

2017-11-21  Maxim Ostapenko  

	PR sanitizer/81697
	* g++.dg/asan/global-alignment.C: New test.

diff --git a/gcc/asan.c b/gcc/asan.c
index d5128aa..78c3b60 100644
--- a/gcc/asan.c
+++ b/gcc/asan.c
@@ -1605,7 +1605,7 @@ is_odr_indicator (tree decl)
ASAN_RED_ZONE_SIZE bytes.  */
 
 bool
-asan_protect_global (tree decl)
+asan_protect_global (tree decl, bool ignore_decl_rtl_set_p)
 {
   if (!ASAN_GLOBALS)
 return false;
@@ -1627,7 +1627,13 @@ asan_protect_global (tree decl)
   || DECL_THREAD_LOCAL_P (decl)
   /* Externs will be protected elsewhere.  */
   || DECL_EXTERNAL (decl)
-  || !DECL_RTL_SET_P (decl)
+  /* PR sanitizer/81697: For architectures that use section anchors first
+	 call to asan_protect_global may occur before DECL_RTL (decl) is set.
+	 We should ignore DECL_RTL_SET_P then, because otherwise the first call
+	 to asan_protect_global will return FALSE and the following calls on the
+	 same decl after setting DECL_RTL (decl) will return TRUE and we'll end
+	 up with inconsistency at runtime.  */
+  || (!DECL_RTL_SET_P (decl) && !ignore_decl_rtl_set_p)
   /* Comdat vars pose an ABI problem, we can't know if
 	 the var that is selected by the linker will have
 	 padding or not.  */
@@ -1651,6 +1657,9 @@ asan_protect_global (tree decl)
   || is_odr_indicator (decl))
 return false;
 
+  if (ignore_decl_rtl_set_p)
+return true;
+
   rtl = DECL_RTL (decl);
   if (!MEM_P (rtl) || GET_CODE (XEXP (rtl, 0)) != SYMBOL_REF)
 return false;
diff --git a/gcc/asan.h b/gcc/asan.h
index c82d4d9..885b47e 100644
--- a/gcc/asan.h
+++ b/gcc/asan.h
@@ -26,7 +26,7 @@ extern void asan_finish_file (void);
 extern rtx_insn *asan_emit_stack_protection (rtx, rtx, unsigned int,
 	 HOST_WIDE_INT *, tree *, int);
 extern rtx_insn *asan_emit_allocas_unpoison (rtx, rtx, rtx_insn *);
-extern bool asan_protect_global (tree);
+extern bool asan_protect_global (tree, bool ignore_decl_rtl_set_p = false);
 extern void initialize_sanitizer_builtins (void);
 extern tree asan_dynamic_init_call (bool);
 extern bool asan_expand_check_ifn (gimple_stmt_iterator *, bool);
diff --git a/gcc/testsuite/g++.dg/asan/global-alignment.C b/gcc/testsuite/g++.dg/asan/global-alignment.C
new file mode 100644
index 000..84dac37
--- /dev/null
+++ b/gcc/testsuite/g++.dg/asan/global-alignment.C
@@ -0,0 +1,18 @@
+/* { dg-options "-fmerge-all-constants" } */
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } { "" } } */
+
+#include 
+#include 
+
+const char kRecoveryInstallString[] = "NEW";
+const char kRecoveryUpdateString[] = "UPDATE";
+const char kRecoveryUninstallationString[] = "UNINSTALL";
+
+const std::map kStringToRequestMap = {
+  {kRecoveryInstallString, 0},
+  {kRecoveryUpdateString, 0},
+  {kRecoveryUninstallationString, 0},
+};
+
+/* { dg-final { scan-assembler-times {\.section\s+\.rodata\n(?:(?!\.section).)*\.\w+\s+"NEW} 1 } } */
diff --git a/gcc/varasm.c b/gcc/varasm.c
index a139151..849eae0 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -6508,7 +6508,7 @@ categorize_decl_for_section (const_tree decl, int reloc)
   else if (TREE_CODE (decl) == STRING_CST)
 {
   if ((flag_sanitize & SANITIZE_ADDRESS)
-	  && asan_protect_global (CONST_CAST_TREE (decl)))
+	  && asan_protect_global (CONST_CAST_TREE (decl), true))
   /* or !flag_merge_constants */
 return SECCAT_RODATA;
   else
@@ -6536,7 +6536,7 @@ categorize_decl_for_section (const_tree decl, int reloc)
 	ret = reloc == 1 ? SECCAT_DATA_REL_RO_LOCAL : SECCAT_DATA_REL_RO;
   else if (reloc || flag_merge_constants < 2
 	   || ((flag_sanitize & SANITIZE_ADDRESS)
-		   && asan_protect_global (CONST_CAST_TREE (decl
+		   && asan_protect_global (CONST_CAST_TREE (decl), true)))
 	/* C and C++ don't allow different variables to share the same
 	   location.  -fmerge-all-constants allows even that (at the
 	   expense of not conforming).  */


Re: [Ping][PATCH v3] Fix Incorrect ASan global variables alignment on arm (PR sanitizer/81697)

2017-11-27 Thread Maxim Ostapenko

(CC'ing Jakub and Ramana)

Hi,

I would like to ping the following patch:
https://gcc.gnu.org/ml/gcc-patches/2017-10/msg02288.html
Fix Incorrect ASan global variables alignment on arm (PR sanitizer/81697)

-Maxim
gcc/ChangeLog:

2017-11-28  Maxim Ostapenko  

	PR sanitizer/81697
	* asan.c (asan_protect_global): Add new ignore_decl_rtl_set_p
	parameter. Return true if ignore_decl_rtl_set_p is true and other
	conditions are satisfied.
	* asan.h (asan_protect_global): Add new parameter.
	* varasm.c (categorize_decl_for_section): Pass true as second parameter
	to asan_protect_global calls.

gcc/testsuite/ChangeLog:

2017-11-28  Maxim Ostapenko  

	PR sanitizer/81697
	* g++.dg/asan/global-alignment.C: New test.

diff --git a/gcc/asan.c b/gcc/asan.c
index d5128aa..78c3b60 100644
--- a/gcc/asan.c
+++ b/gcc/asan.c
@@ -1605,7 +1605,7 @@ is_odr_indicator (tree decl)
ASAN_RED_ZONE_SIZE bytes.  */
 
 bool
-asan_protect_global (tree decl)
+asan_protect_global (tree decl, bool ignore_decl_rtl_set_p)
 {
   if (!ASAN_GLOBALS)
 return false;
@@ -1627,7 +1627,13 @@ asan_protect_global (tree decl)
   || DECL_THREAD_LOCAL_P (decl)
   /* Externs will be protected elsewhere.  */
   || DECL_EXTERNAL (decl)
-  || !DECL_RTL_SET_P (decl)
+  /* PR sanitizer/81697: For architectures that use section anchors first
+	 call to asan_protect_global may occur before DECL_RTL (decl) is set.
+	 We should ignore DECL_RTL_SET_P then, because otherwise the first call
+	 to asan_protect_global will return FALSE and the following calls on the
+	 same decl after setting DECL_RTL (decl) will return TRUE and we'll end
+	 up with inconsistency at runtime.  */
+  || (!DECL_RTL_SET_P (decl) && !ignore_decl_rtl_set_p)
   /* Comdat vars pose an ABI problem, we can't know if
 	 the var that is selected by the linker will have
 	 padding or not.  */
@@ -1651,6 +1657,9 @@ asan_protect_global (tree decl)
   || is_odr_indicator (decl))
 return false;
 
+  if (ignore_decl_rtl_set_p)
+return true;
+
   rtl = DECL_RTL (decl);
   if (!MEM_P (rtl) || GET_CODE (XEXP (rtl, 0)) != SYMBOL_REF)
 return false;
diff --git a/gcc/asan.h b/gcc/asan.h
index c82d4d9..885b47e 100644
--- a/gcc/asan.h
+++ b/gcc/asan.h
@@ -26,7 +26,7 @@ extern void asan_finish_file (void);
 extern rtx_insn *asan_emit_stack_protection (rtx, rtx, unsigned int,
 	 HOST_WIDE_INT *, tree *, int);
 extern rtx_insn *asan_emit_allocas_unpoison (rtx, rtx, rtx_insn *);
-extern bool asan_protect_global (tree);
+extern bool asan_protect_global (tree, bool ignore_decl_rtl_set_p = false);
 extern void initialize_sanitizer_builtins (void);
 extern tree asan_dynamic_init_call (bool);
 extern bool asan_expand_check_ifn (gimple_stmt_iterator *, bool);
diff --git a/gcc/testsuite/g++.dg/asan/global-alignment.C b/gcc/testsuite/g++.dg/asan/global-alignment.C
new file mode 100644
index 000..84dac37
--- /dev/null
+++ b/gcc/testsuite/g++.dg/asan/global-alignment.C
@@ -0,0 +1,18 @@
+/* { dg-options "-fmerge-all-constants" } */
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } { "" } } */
+
+#include 
+#include 
+
+const char kRecoveryInstallString[] = "NEW";
+const char kRecoveryUpdateString[] = "UPDATE";
+const char kRecoveryUninstallationString[] = "UNINSTALL";
+
+const std::map kStringToRequestMap = {
+  {kRecoveryInstallString, 0},
+  {kRecoveryUpdateString, 0},
+  {kRecoveryUninstallationString, 0},
+};
+
+/* { dg-final { scan-assembler-times {\.section\s+\.rodata\n(?:(?!\.section).)*\.\w+\s+"NEW} 1 } } */
diff --git a/gcc/varasm.c b/gcc/varasm.c
index a139151..849eae0 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -6508,7 +6508,7 @@ categorize_decl_for_section (const_tree decl, int reloc)
   else if (TREE_CODE (decl) == STRING_CST)
 {
   if ((flag_sanitize & SANITIZE_ADDRESS)
-	  && asan_protect_global (CONST_CAST_TREE (decl)))
+	  && asan_protect_global (CONST_CAST_TREE (decl), true))
   /* or !flag_merge_constants */
 return SECCAT_RODATA;
   else
@@ -6536,7 +6536,7 @@ categorize_decl_for_section (const_tree decl, int reloc)
 	ret = reloc == 1 ? SECCAT_DATA_REL_RO_LOCAL : SECCAT_DATA_REL_RO;
   else if (reloc || flag_merge_constants < 2
 	   || ((flag_sanitize & SANITIZE_ADDRESS)
-		   && asan_protect_global (CONST_CAST_TREE (decl
+		   && asan_protect_global (CONST_CAST_TREE (decl), true)))
 	/* C and C++ don't allow different variables to share the same
 	   location.  -fmerge-all-constants allows even that (at the
 	   expense of not conforming).  */


Re: [Ping][PATCH v3] Fix Incorrect ASan global variables alignment on arm (PR sanitizer/81697)

2017-11-30 Thread Maxim Ostapenko

Hi Jakub, thanks for review.

I've fixed the issues you've pointed in review.
Regarding a testcase -- I've cooked a runtime test, but it shows FP on 
unpatched GCC version only when linking with Gold (because it strips 
redzones more aggressively).


This patch passes tests on arm-linux and x86_64-linux, bootstrap is in 
progress.


Thanks,
-Maxim

On 29/11/17 13:10, Jakub Jelinek wrote:

On Tue, Nov 28, 2017 at 10:04:51AM +0300, Maxim Ostapenko wrote:

(CC'ing Jakub and Ramana)

I would like to ping the following patch:
https://gcc.gnu.org/ml/gcc-patches/2017-10/msg02288.html
Fix Incorrect ASan global variables alignment on arm (PR sanitizer/81697)

-Maxim
gcc/ChangeLog:

2017-11-28  Maxim Ostapenko  

PR sanitizer/81697
* asan.c (asan_protect_global): Add new ignore_decl_rtl_set_p
parameter. Return true if ignore_decl_rtl_set_p is true and other
conditions are satisfied.
* asan.h (asan_protect_global): Add new parameter.
* varasm.c (categorize_decl_for_section): Pass true as second parameter
to asan_protect_global calls.

gcc/testsuite/ChangeLog:

2017-11-28  Maxim Ostapenko  

PR sanitizer/81697
* g++.dg/asan/global-alignment.C: New test.

diff --git a/gcc/asan.c b/gcc/asan.c
index d5128aa..78c3b60 100644
--- a/gcc/asan.c
+++ b/gcc/asan.c
@@ -1605,7 +1605,7 @@ is_odr_indicator (tree decl)
 ASAN_RED_ZONE_SIZE bytes.  */
  
  bool

-asan_protect_global (tree decl)
+asan_protect_global (tree decl, bool ignore_decl_rtl_set_p)
  {
if (!ASAN_GLOBALS)
  return false;
@@ -1627,7 +1627,13 @@ asan_protect_global (tree decl)
|| DECL_THREAD_LOCAL_P (decl)
/* Externs will be protected elsewhere.  */
|| DECL_EXTERNAL (decl)
-  || !DECL_RTL_SET_P (decl)
+  /* PR sanitizer/81697: For architectures that use section anchors first
+call to asan_protect_global may occur before DECL_RTL (decl) is set.
+We should ignore DECL_RTL_SET_P then, because otherwise the first call
+to asan_protect_global will return FALSE and the following calls on the
+same decl after setting DECL_RTL (decl) will return TRUE and we'll end
+up with inconsistency at runtime.  */
+  || (!DECL_RTL_SET_P (decl) && !ignore_decl_rtl_set_p)

This part is fine.


/* Comdat vars pose an ABI problem, we can't know if
 the var that is selected by the linker will have
 padding or not.  */
@@ -1651,6 +1657,9 @@ asan_protect_global (tree decl)
|| is_odr_indicator (decl))
  return false;
  
+  if (ignore_decl_rtl_set_p)

+return true;

This isn't, because then you bypass checks that really don't care
about RTL, like:
  if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl)))
return false;

  if (!TARGET_SUPPORTS_ALIASES && asan_needs_local_alias (decl))
return false;

So, IMHO just wrap only the DECL_RTL/symbol related stuff in if
(!ignore_decl_rtl_set_p).  Perhaps even better in
if (!ignore_decl_rtl_set_p || DECL_RTL_SET_P (decl))
so that if the rtl is already set, you do the check anyway.


--- /dev/null
+++ b/gcc/testsuite/g++.dg/asan/global-alignment.C
@@ -0,0 +1,18 @@
+/* { dg-options "-fmerge-all-constants" } */
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } { "" } } */
+
+#include 
+#include 
+
+const char kRecoveryInstallString[] = "NEW";
+const char kRecoveryUpdateString[] = "UPDATE";
+const char kRecoveryUninstallationString[] = "UNINSTALL";
+
+const std::map kStringToRequestMap = {
+  {kRecoveryInstallString, 0},
+  {kRecoveryUpdateString, 0},
+  {kRecoveryUninstallationString, 0},
+};
+
+/* { dg-final { scan-assembler-times 
{\.section\s+\.rodata\n(?:(?!\.section).)*\.\w+\s+"NEW} 1 } } */

I don't really like the testcase.  The scaning for .rodata section is too
fragile, e.g. darwin will need something completely different, doesn't e.g.
powerpc use .sdata section instead, etc.

And, isn't std::map and std::string completely unnecessary?
I'd prefer a runtime test that shows the false positive without the patch,
preferrably in C, just with those const char arrays used by some C code
without any headers.


diff --git a/gcc/varasm.c b/gcc/varasm.c
index a139151..849eae0 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -6508,7 +6508,7 @@ categorize_decl_for_section (const_tree decl, int reloc)
else if (TREE_CODE (decl) == STRING_CST)
  {
if ((flag_sanitize & SANITIZE_ADDRESS)
- && asan_protect_global (CONST_CAST_TREE (decl)))
+ && asan_protect_global (CONST_CAST_TREE (decl), true))

This doesn't make sense to me.  asan_protect_global for STRING_CST doesn't
care about any RTL, nor -fsection-anchors puts them into any kind of
block.


/* or !flag_mer

Re: [Ping][PATCH v3] Fix Incorrect ASan global variables alignment on arm (PR sanitizer/81697)

2017-11-30 Thread Maxim Ostapenko
Ok, thanks, here is the patch I'm going to install after bootstrap 
completes.


On 30/11/17 14:54, Jakub Jelinek wrote:

On Thu, Nov 30, 2017 at 02:38:25PM +0300, Maxim Ostapenko wrote:

Hi Jakub, thanks for review.

I've fixed the issues you've pointed in review.
Regarding a testcase -- I've cooked a runtime test, but it shows FP on
unpatched GCC version only when linking with Gold (because it strips
redzones more aggressively).

I think we can live with that.


--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -6550,7 +6550,19 @@ categorize_decl_for_section (const_tree decl, int reloc)
ret = reloc == 1 ? SECCAT_DATA_REL_RO_LOCAL : SECCAT_DATA_REL_RO;
else if (reloc || flag_merge_constants < 2
   || ((flag_sanitize & SANITIZE_ADDRESS)
-  && asan_protect_global (CONST_CAST_TREE (decl
+  /* PR 81697: for architectures that use section anchors we
+ need to ignore DECL_RTL_SET_P (decl) for string constants
+ inside this asan_protect_global call because otherwise
+ we'll wrongly put them into SECCAT_RODATA_MERGE_CONST
+ section, set DECL_RTL (decl) later on and add DECL to
+ protected globals via successive asan_protect_global
+ calls.  In this scenario we'll end up with wrong
+ alignment of these strings at runtime and possible ASan
+ false positives.  */
+  && asan_protect_global (CONST_CAST_TREE (decl),
+  use_object_blocks_p ()
+&& use_blocks_for_decl_p (
+ CONST_CAST_TREE (decl)

Formatting is too bad here.  && should go below use_object_block_p..
The opening ( should either go on the next line, like:
   use_object_blocks_p ()
   && use_blocks_for_decl_p
(CONST_CAST_TREE (decl)
or perhaps better just introduce a temporary somewhere:
else if (VAR_P (decl))
  {
+  tree d = CONST_CAST_TREE (decl);
if (bss_initializer_p (decl))
  ret = SECCAT_BSS;
and use d instead of CONST_CAST_TREE (decl) later?

Ok with those changes.

Jakub





gcc/ChangeLog:

2017-11-30  Maxim Ostapenko  

	PR sanitizer/81697
	* asan.c (asan_protect_global): Add new ignore_decl_rtl_set_p
	parameter. Return true if ignore_decl_rtl_set_p is true and other
	conditions are satisfied.
	* asan.h (asan_protect_global): Add new parameter.
	* varasm.c (categorize_decl_for_section): Pass true as second parameter
	to asan_protect_global calls.

gcc/testsuite/ChangeLog:

2017-11-30  Maxim Ostapenko  

	PR sanitizer/81697
	* c-c++-common/asan/pr81697.c: New test.

diff --git a/gcc/asan.c b/gcc/asan.c
index ca5fceed..873687f 100644
--- a/gcc/asan.c
+++ b/gcc/asan.c
@@ -1605,7 +1605,7 @@ is_odr_indicator (tree decl)
ASAN_RED_ZONE_SIZE bytes.  */
 
 bool
-asan_protect_global (tree decl)
+asan_protect_global (tree decl, bool ignore_decl_rtl_set_p)
 {
   if (!ASAN_GLOBALS)
 return false;
@@ -1627,7 +1627,13 @@ asan_protect_global (tree decl)
   || DECL_THREAD_LOCAL_P (decl)
   /* Externs will be protected elsewhere.  */
   || DECL_EXTERNAL (decl)
-  || !DECL_RTL_SET_P (decl)
+  /* PR sanitizer/81697: For architectures that use section anchors first
+	 call to asan_protect_global may occur before DECL_RTL (decl) is set.
+	 We should ignore DECL_RTL_SET_P then, because otherwise the first call
+	 to asan_protect_global will return FALSE and the following calls on the
+	 same decl after setting DECL_RTL (decl) will return TRUE and we'll end
+	 up with inconsistency at runtime.  */
+  || (!DECL_RTL_SET_P (decl) && !ignore_decl_rtl_set_p)
   /* Comdat vars pose an ABI problem, we can't know if
 	 the var that is selected by the linker will have
 	 padding or not.  */
@@ -1651,14 +1657,18 @@ asan_protect_global (tree decl)
   || is_odr_indicator (decl))
 return false;
 
-  rtl = DECL_RTL (decl);
-  if (!MEM_P (rtl) || GET_CODE (XEXP (rtl, 0)) != SYMBOL_REF)
-return false;
-  symbol = XEXP (rtl, 0);
+  if (!ignore_decl_rtl_set_p || DECL_RTL_SET_P (decl))
+{
 
-  if (CONSTANT_POOL_ADDRESS_P (symbol)
-  || TREE_CONSTANT_POOL_ADDRESS_P (symbol))
-return false;
+  rtl = DECL_RTL (decl);
+  if (!MEM_P (rtl) || GET_CODE (XEXP (rtl, 0)) != SYMBOL_REF)
+	return false;
+  symbol = XEXP (rtl, 0);
+
+  if (CONSTANT_POOL_ADDRESS_P (symbol)
+	  || TREE_CONSTANT_POOL_ADDRESS_P (symbol))
+	return false;
+}
 
   if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl)))
 return false;
diff --git a/gcc/asan.h b/gcc/asan.h
index c82d4d9..885b47e 100644

Re: [PATCH][PR sanitizer/86090] Add checks for lstat and readlink to sanitizer configure.

2018-06-13 Thread Maxim Ostapenko
Hi,


On 06/10/2018 09:49 PM, Jakub Jelinek wrote:
> On Fri, Jun 08, 2018 at 08:10:40PM +0300, Denis Khalikov wrote:
>> From: Denis Khalikov 
>> Date: Fri, 8 Jun 2018 19:53:01 +0300
>> Subject: [PATCH] PR sanitizer/86090
>>
>> * configure.ac: Check for lstat and readlink.
>> * configure, config.h.in: Rebuild.
> Ok for trunk.  Will somebody commit it for you or should I?

sorry for the delay, we had public holidays at the beginning of this 
week. I'll commit this today.

-Maxim

>
>   Jakub
>
>
>



[PATCH][PR sanitizer/78651] Incorrect exception handling when catch clause uses local class and PIC and sanitizer are active

2018-03-19 Thread Maxim Ostapenko

Hi,


as noted in bugzilla, ASan inserts redzones for  `.LDFCM*' variables and 
breaks internal ABI between GCC and libstdc++ because libstdc++ tries to 
obtain a pointer to `typeinfo for (anonymous namespace)::SomeRandomType' 
from a constant offset from `.LDFCM*' labels and hits these redzones. 
This can be trivially fixed by not sanitizing `.LDFCM*' variables (and 
other debug variables) at all.


Attached patch is tested/bootstrapped on x86_64-unknown-linux-gnu and 
ppc64le-redhat-linux targets.


Is it OK for trunk now, or should I wait for stage 1?


-Maxim

gcc/

	PR sanitizer/78651
	* dwarf2asm.c (dw2_output_indirect_constant_1): Call
	assemble_variable with new parameter.
	* output.h (assemble_variable): Add new parameter.
	* varasm.c (assemble_variable): Add new parameter. Do not
	protect variable with ASan if is_debug_var is true.

gcc/testsuite/ChangeLog:

	PR sanitizer/78651
	* g++.dg/asan/pr78651.C: New test.

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b5b5559..a26f05e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2018-03-19  Maxim Ostapenko  
+
+	PR sanitizer/78651
+	* dwarf2asm.c (dw2_output_indirect_constant_1): Call assemble_variable
+	with new parameter.
+	* output.h (assemble_variable): Add new parameter.
+	* varasm.c (assemble_variable): Add new parameter. Do not protect
+	variable with ASan if is_debug_var is true.
+
 2018-03-19  Richard Biener  
 
 	PR tree-optimization/84929
diff --git a/gcc/dwarf2asm.c b/gcc/dwarf2asm.c
index e9b18b8..5c90994 100644
--- a/gcc/dwarf2asm.c
+++ b/gcc/dwarf2asm.c
@@ -967,7 +967,7 @@ dw2_output_indirect_constant_1 (const char *sym, tree id)
 }
 
   sym_ref = gen_rtx_SYMBOL_REF (Pmode, sym);
-  assemble_variable (decl, 1, 1, 1);
+  assemble_variable (decl, 1, 1, 1, 1);
   assemble_integer (sym_ref, POINTER_SIZE_UNITS, POINTER_SIZE, 1);
 
   return 0;
diff --git a/gcc/output.h b/gcc/output.h
index f708cc7..678c370 100644
--- a/gcc/output.h
+++ b/gcc/output.h
@@ -200,7 +200,7 @@ extern void assemble_end_function (tree, const char *);
to define things that have had only tentative definitions.
DONT_OUTPUT_DATA if nonzero means don't actually output the
initial value (that will be done by the caller).  */
-extern void assemble_variable (tree, int, int, int);
+extern void assemble_variable (tree, int, int, int, int is_debug_var = 0);
 
 /* Put the vtable verification constructor initialization function
into the preinit array.  */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 868d8e8..6ff9217 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2018-03-19  Maxim Ostapenko  
+
+	PR sanitizer/78651
+	* g++.dg/asan/pr78651.C: New test.
+
 2018-03-19  Richard Biener  
 
 	PR tree-optimization/84929
diff --git a/gcc/testsuite/g++.dg/asan/pr78651.C b/gcc/testsuite/g++.dg/asan/pr78651.C
new file mode 100644
index 000..3f14be7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/asan/pr78651.C
@@ -0,0 +1,24 @@
+// { dg-do run { target fpic } }
+
+struct A { };
+
+namespace {
+
+void thisThrows () {
+  throw A();
+}
+
+struct SomeRandomType {};
+}
+
+int main() {
+  try {
+thisThrows();
+  }
+  catch (SomeRandomType) {
+throw;
+  }
+  catch (A) {
+  }
+  return 0;
+}
diff --git a/gcc/varasm.c b/gcc/varasm.c
index 2b5c70c..b18d011 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -2158,11 +2158,14 @@ assemble_undefined_decl (tree decl)
AT_END is nonzero if this is the special handling, at end of compilation,
to define things that have had only tentative definitions.
DONT_OUTPUT_DATA if nonzero means don't actually output the
-   initial value (that will be done by the caller).  */
+   initial value (that will be done by the caller).
+   IS_DEBUG_VAR if nonzero that we are assembling debug variable.
+   This information is useful for ASan, see pr78651.  */
 
 void
 assemble_variable (tree decl, int top_level ATTRIBUTE_UNUSED,
-		   int at_end ATTRIBUTE_UNUSED, int dont_output_data)
+		   int at_end ATTRIBUTE_UNUSED, int dont_output_data,
+		   int is_debug_var)
 {
   const char *name;
   rtx decl_rtl, symbol;
@@ -2258,6 +2261,7 @@ assemble_variable (tree decl, int top_level ATTRIBUTE_UNUSED,
   align_variable (decl, dont_output_data);
 
   if ((flag_sanitize & SANITIZE_ADDRESS)
+  && !is_debug_var
   && asan_protect_global (decl))
 {
   asan_protected = true;


Re: [PATCH][PR sanitizer/78651] Incorrect exception handling when catch clause uses local class and PIC and sanitizer are active

2018-03-19 Thread Maxim Ostapenko

On 03/19/2018 06:55 PM, Jakub Jelinek wrote:

On Mon, Mar 19, 2018 at 06:44:39PM +0300, Maxim Ostapenko wrote:

as noted in bugzilla, ASan inserts redzones for  `.LDFCM*' variables and
breaks internal ABI between GCC and libstdc++ because libstdc++ tries to
obtain a pointer to `typeinfo for (anonymous namespace)::SomeRandomType'
from a constant offset from `.LDFCM*' labels and hits these redzones. This
can be trivially fixed by not sanitizing `.LDFCM*' variables (and other
debug variables) at all.

I don't like very much adding an extra argument for such so frequently used
function to handle a corner case.
Wouldn't just:
   /* Don't instrument this decl with -fsanitize=*address.  */
   unsigned int save_flag_sanitize = flag_sanitize;
   flag_sanitize &= ~(SANITIZE_ADDRESS | SANITIZE_USER_ADDRESS
 | SANITIZE_KERNEL_ADDRESS);
   assemble_variable (decl, 1, 1, 1);
   flag_sanitize = save_flag_sanitize;
DTRT?




Yes, it works, attaching the patch.

-Maxim
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b5b5559..356e68c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2018-03-19  Maxim Ostapenko  
+
+	PR sanitizer/78651
+	* dwarf2asm.c (dw2_output_indirect_constant_1): Disable ASan before
+	calling assemble_variable.
+
 2018-03-19  Richard Biener  
 
 	PR tree-optimization/84929
diff --git a/gcc/dwarf2asm.c b/gcc/dwarf2asm.c
index e9b18b8..065406b 100644
--- a/gcc/dwarf2asm.c
+++ b/gcc/dwarf2asm.c
@@ -967,7 +967,11 @@ dw2_output_indirect_constant_1 (const char *sym, tree id)
 }
 
   sym_ref = gen_rtx_SYMBOL_REF (Pmode, sym);
+  unsigned int save_flag_sanitize = flag_sanitize;
+  flag_sanitize &= ~(SANITIZE_ADDRESS | SANITIZE_USER_ADDRESS
+		 | SANITIZE_KERNEL_ADDRESS);
   assemble_variable (decl, 1, 1, 1);
+  flag_sanitize = save_flag_sanitize;
   assemble_integer (sym_ref, POINTER_SIZE_UNITS, POINTER_SIZE, 1);
 
   return 0;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 868d8e8..6ff9217 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2018-03-19  Maxim Ostapenko  
+
+	PR sanitizer/78651
+	* g++.dg/asan/pr78651.C: New test.
+
 2018-03-19  Richard Biener  
 
 	PR tree-optimization/84929
diff --git a/gcc/testsuite/g++.dg/asan/pr78651.C b/gcc/testsuite/g++.dg/asan/pr78651.C
new file mode 100644
index 000..3f14be7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/asan/pr78651.C
@@ -0,0 +1,24 @@
+// { dg-do run { target fpic } }
+
+struct A { };
+
+namespace {
+
+void thisThrows () {
+  throw A();
+}
+
+struct SomeRandomType {};
+}
+
+int main() {
+  try {
+thisThrows();
+  }
+  catch (SomeRandomType) {
+throw;
+  }
+  catch (A) {
+  }
+  return 0;
+}


Re: [PATCH][PR sanitizer/78651] Incorrect exception handling when catch clause uses local class and PIC and sanitizer are active

2018-03-19 Thread Maxim Ostapenko

On 03/19/2018 07:35 PM, Jakub Jelinek wrote:

On Mon, Mar 19, 2018 at 07:28:11PM +0300, Maxim Ostapenko wrote:

Yes, it works, attaching the patch.

Can you please add a short comment why we do this?  Also, the testcase
needs work, see below.  Ok for trunk with those changes and after a
while for affected release branches as well.


Ok, thanks, attaching the patch I'm going to apply.

-Maxim
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b5b5559..356e68c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2018-03-19  Maxim Ostapenko  
+
+	PR sanitizer/78651
+	* dwarf2asm.c (dw2_output_indirect_constant_1): Disable ASan before
+	calling assemble_variable.
+
 2018-03-19  Richard Biener  
 
 	PR tree-optimization/84929
diff --git a/gcc/dwarf2asm.c b/gcc/dwarf2asm.c
index e9b18b8..2e108ac 100644
--- a/gcc/dwarf2asm.c
+++ b/gcc/dwarf2asm.c
@@ -967,7 +967,13 @@ dw2_output_indirect_constant_1 (const char *sym, tree id)
 }
 
   sym_ref = gen_rtx_SYMBOL_REF (Pmode, sym);
+  /* Disable ASan for decl because redzones cause ABI breakage between GCC and
+ libstdc++ for `.LDFCM*' variables.  See PR 78651 for details.  */
+  unsigned int save_flag_sanitize = flag_sanitize;
+  flag_sanitize &= ~(SANITIZE_ADDRESS | SANITIZE_USER_ADDRESS
+		 | SANITIZE_KERNEL_ADDRESS);
   assemble_variable (decl, 1, 1, 1);
+  flag_sanitize = save_flag_sanitize;
   assemble_integer (sym_ref, POINTER_SIZE_UNITS, POINTER_SIZE, 1);
 
   return 0;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 868d8e8..6ff9217 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2018-03-19  Maxim Ostapenko  
+
+	PR sanitizer/78651
+	* g++.dg/asan/pr78651.C: New test.
+
 2018-03-19  Richard Biener  
 
 	PR tree-optimization/84929
diff --git a/gcc/testsuite/g++.dg/asan/pr78651.C b/gcc/testsuite/g++.dg/asan/pr78651.C
new file mode 100644
index 000..09f1be5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/asan/pr78651.C
@@ -0,0 +1,26 @@
+// PR sanitizer/78651
+// { dg-do run }
+// { dg-additional-options "-fpic" { target fpic } }
+
+struct A { };
+
+namespace {
+
+void thisThrows () {
+  throw A();
+}
+
+struct SomeRandomType {};
+}
+
+int main() {
+  try {
+thisThrows();
+  }
+  catch (SomeRandomType) {
+throw;
+  }
+  catch (A) {
+  }
+  return 0;
+}


Re: [PATCH] Fix -fsanitize=address VLA instrumentation (PR sanitizer/85230)

2018-04-13 Thread Maxim Ostapenko
On 04/13/2018 01:16 AM, Jakub Jelinek wrote:
> Hi!
>
> As mentioned in the PR, we need to unpoison the red zones when leaving a
> scope with VLA variable(s); this is done through __asan_allocas_unpoison
> call, unfortunately it is called after the __builtin_stack_restore which
> restores the stack pointer; now, if an interrupt comes in between the stack
> restore and the __asan_allocas_unpoison call, the interrupt handler might
> have some stack bytes marked as red zones in the shadow memory and might
> diagnose sanitizing error even when there is none in the original program.
>
> The following patch ought to fix this by swapping the two calls, so we first
> unpoison and only after it is unpoisoned in shadow memory release the stack.
> The second argument to the __asan_allocas_unpoison call is meant to
> be virtual_dynamic_stack_rtx after the __builtin_stack_restore, i.e. the new
> stack_pointer_rtx value + STACK_DYNAMIC_OFFSET (current_function_decl).
> As the STACK_DYNAMIC_OFFSET value isn't known until the vregs pass, the code
> used a hack where it ignored the second argument and replaced it by
> virtual_dynamic_stack_rtx.  With the asan.c change below this doesn't work
> anymore, because virtual_dynamic_stack_rtx aka stack_pointer_rtx +
> STACK_DYNAMIC_OFFSET (current_function_decl) before the
> __builtin_stack_restore is a different value.  The patch instead uses the
> argument passed to the __asan_allocas_unpoison at GIMPLE time, which is the
> same as passed to __builtin_stack_restore; this is the new stack_pointer_rtx
> value after __builtin_stack_restore.  And, because we don't want that value,
> but that + STACK_DYNAMIC_OFFSET (current_function_decl), we compute
> arg1 + (virtual_dynamic_stack_rtx - stack_pointer_rtx) and let CSE/combiner
> optimize it into arg1 (on targets like x86_64 where STACK_DYNAMIC_OFFSET can
> be even 0 when not accumulating outgoing args or when that size is 0) or
> arg1 + some_constant.
>
> Bootstrapped on
> {x86_64,i686,powerpc64,powerpc64le,aarch64,s390x,armv7hl}-linux, regtested
> on {x86_64,i686,powerpc64,powerpc64le}-linux so far, but on the power* ones
> on virtual address space size that isn't really supported (likely
> https://github.com/google/sanitizers/issues/933#issuecomment-380058705
> issue, so while nothing regresses there, pretty much all asan tests fail
> there before and after the patch); also tested successfully with
> asan.exp=alloca* on gcc110 and gcc112 on compile farm where it doesn't
> suffer from the VA issue.  Ok if testing passes also on aarch64, s390x
> and armv7hl?

OK with me, thanks.

-Maxim

> 2018-04-12  Jakub Jelinek  
>
>   PR sanitizer/85230
>   * asan.c (handle_builtin_stack_restore): Adjust comment.  Emit
>   __asan_allocas_unpoison call and last_alloca_addr = new_sp before
>   __builtin_stack_restore rather than after it.
>   * builtins.c (expand_asan_emit_allocas_unpoison): Pass
>   arg1 + (virtual_dynamic_stack_rtx - stack_pointer_rtx) as second
>   argument instead of virtual_dynamic_stack_rtx.
>
> --- gcc/asan.c.jj 2018-01-09 21:53:38.821577722 +0100
> +++ gcc/asan.c2018-04-12 13:22:59.166095523 +0200
> @@ -554,14 +554,14 @@ get_last_alloca_addr ()
> return last_alloca_addr;
>   }
>   
> -/* Insert __asan_allocas_unpoison (top, bottom) call after
> +/* Insert __asan_allocas_unpoison (top, bottom) call before
>  __builtin_stack_restore (new_sp) call.
>  The pseudocode of this routine should look like this:
> - __builtin_stack_restore (new_sp);
>top = last_alloca_addr;
>bot = new_sp;
>__asan_allocas_unpoison (top, bot);
>last_alloca_addr = new_sp;
> + __builtin_stack_restore (new_sp);
>  In general, we can't use new_sp as bot parameter because on some
>  architectures SP has non zero offset from dynamic stack area.  Moreover, 
> on
>  some architectures this offset (STACK_DYNAMIC_OFFSET) becomes known for 
> each
> @@ -570,9 +570,8 @@ get_last_alloca_addr ()
>  
> http://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi.html#DYNAM-STACK.
>  To overcome the issue we use following trick: pass new_sp as a second
>  parameter to __asan_allocas_unpoison and rewrite it during expansion with
> -   virtual_dynamic_stack_rtx later in expand_asan_emit_allocas_unpoison
> -   function.
> -*/
> +   new_sp + (virtual_dynamic_stack_rtx - sp) later in
> +   expand_asan_emit_allocas_unpoison function.  */
>   
>   static void
>   handle_builtin_stack_restore (gcall *call, gimple_stmt_iterator *iter)
> @@ -584,9 +583,9 @@ handle_builtin_stack_restore (gcall *cal
> tree restored_stack = gimple_call_arg (call, 0);
> tree fn = builtin_decl_implicit (BUILT_IN_ASAN_ALLOCAS_UNPOISON);
> gimple *g = gimple_build_call (fn, 2, last_alloca, restored_stack);
> -  gsi_insert_after (iter, g, GSI_NEW_STMT);
> +  gsi_insert_before (iter, g, GSI_SAME_STMT);
> g = gimple_build_assign (last_alloca, restored_stack);
> -  gsi_insert_a

[PATCH][PR sanitizer/84250] Avoid global symbols collision when using both ASan and UBSan

2018-05-23 Thread Maxim Ostapenko
Hi,


as described in PR, when using both ASan and UBSan 
(-fsanitize=address,undefined ), we have symbols collision for global 
functions, like __sanitizer_set_report_path. This leads to fuzzy results 
when printing reports into files e.g. for this test case:

#include 
int main(int argc, char **argv) {
   __sanitizer_set_report_path("/tmp/sanitizer.txt");
   int i = 23;
   i <<= 32;
   int *array = new int[100];
   delete [] array;
   return array[argc];
}

only ASan's report gets written to file; UBSan output goes to stderr.

To resolve this issue we could use two approaches:

1) Use the same approach to that is implemented in Clang (UBSan embedded 
to ASan). The only caveat here is that we need to link (unused) C++ part 
of UBSan even in C programs when linking static ASan runtime. This 
happens because GCC, as opposed to Clang, doesn't split C and C++ 
runtimes for sanitizers.

2) Just add SANITIZER_INTERFACE_ATTRIBUTE to report_file global 
variable. In this case all __sanitizer_set_report_path calls will set 
the same report_file variable. IMHO this is a hacky way to fix the 
issue, it's better to use the first option if possible.


The attached patch fixes the symbols collision by embedding UBSan into 
ASan (variant 1), just like we do for LSan.


Regtested/bootstrapped on x86_64-unknown-linux-gnu, looks reasonable 
enough for trunk?


-Maxim

gcc/ChangeLog:

2018-05-23  Maxim Ostapenko  

	* config/gnu-user.h (LIBASAN_EARLY_SPEC): Pass -lstdc++ for static
	libasan.
	* gcc.c: Do not pass LIBUBSAN_SPEC if ASan is enabled with UBSan.

libsanitizer/ChangeLog:

2018-05-23  Maxim Ostapenko  

	* Makefile.am: Reorder libs.
	* Makefile.in: Regenerate.
	* asan/Makefile.am: Define DCAN_SANITIZE_UB=1, add dependancy from
	libsanitizer_ubsan.la.
	* asan/Makefile.in: Regenerate.
	* ubsan/Makefile.am: Define new libsanitizer_ubsan.la library.
	* ubsan/Makefile.in: Regenerate.

diff --git a/gcc/config/gnu-user.h b/gcc/config/gnu-user.h
index cba3c0b..ccae957 100644
--- a/gcc/config/gnu-user.h
+++ b/gcc/config/gnu-user.h
@@ -161,7 +161,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #define LIBASAN_EARLY_SPEC "%{!shared:libasan_preinit%O%s} " \
   "%{static-libasan:%{!shared:" \
   LD_STATIC_OPTION " --whole-archive -lasan --no-whole-archive " \
-  LD_DYNAMIC_OPTION "}}%{!static-libasan:-lasan}"
+  LD_DYNAMIC_OPTION " -lstdc++ }}%{!static-libasan:-lasan}"
 #undef LIBTSAN_EARLY_SPEC
 #define LIBTSAN_EARLY_SPEC "%{!shared:libtsan_preinit%O%s} " \
   "%{static-libtsan:%{!shared:" \
diff --git a/gcc/gcc.c b/gcc/gcc.c
index a716f70..215e7a0 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -984,7 +984,7 @@ proper position among the other output files.  */
 %{static:%ecannot specify -static with -fsanitize=address}}\
 %{%:sanitize(thread):" LIBTSAN_SPEC "\
 %{static:%ecannot specify -static with -fsanitize=thread}}\
-%{%:sanitize(undefined):" LIBUBSAN_SPEC "}\
+%{!%:sanitize(address):%{%:sanitize(undefined):" LIBUBSAN_SPEC "}}\
 %{%:sanitize(leak):" LIBLSAN_SPEC "}}}"
 #endif
 
diff --git a/libsanitizer/Makefile.am b/libsanitizer/Makefile.am
index 018f0b0..08d952b 100644
--- a/libsanitizer/Makefile.am
+++ b/libsanitizer/Makefile.am
@@ -14,7 +14,7 @@ endif
 if LIBBACKTRACE_SUPPORTED
 SUBDIRS += libbacktrace
 endif
-SUBDIRS += lsan asan ubsan
+SUBDIRS += lsan ubsan asan
 nodist_saninclude_HEADERS += \
   include/sanitizer/lsan_interface.h \
   include/sanitizer/asan_interface.h \
diff --git a/libsanitizer/Makefile.in b/libsanitizer/Makefile.in
index a9fea21e..9074292 100644
--- a/libsanitizer/Makefile.in
+++ b/libsanitizer/Makefile.in
@@ -140,8 +140,8 @@ AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
 	$(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS
 ETAGS = etags
 CTAGS = ctags
-DIST_SUBDIRS = sanitizer_common interception libbacktrace lsan asan \
-	ubsan tsan
+DIST_SUBDIRS = sanitizer_common interception libbacktrace lsan ubsan \
+	asan tsan
 ACLOCAL = @ACLOCAL@
 ALLOC_FILE = @ALLOC_FILE@
 AMTAR = @AMTAR@
@@ -294,7 +294,7 @@ ACLOCAL_AMFLAGS = -I .. -I ../config
 sanincludedir = $(libdir)/gcc/$(target_alias)/$(gcc_version)/include/sanitizer
 nodist_saninclude_HEADERS = $(am__append_1)
 @SANITIZER_SUPPORTED_TRUE@SUBDIRS = sanitizer_common $(am__append_2) \
-@SANITIZER_SUPPORTED_TRUE@	$(am__append_3) lsan asan ubsan \
+@SANITIZER_SUPPORTED_TRUE@	$(am__append_3) lsan ubsan asan \
 @SANITIZER_SUPPORTED_TRUE@	$(am__append_4)
 gcc_version := $(shell @get_gcc_base_ver@ $(top_srcdir)/../gcc/BASE-VER)
 
diff --git a/libsanitizer/asan/Makefile.am b/libsanitizer/asan/Makefile.am
index f105b03..3ac49ee 100644
--- a/libsanitizer/asan/Makefile.am
+++ b/libsanitizer/asan/Makefile.am
@@ -3,7 +3,7 @@ AM_CPPFLAGS = -I $(top_srcdir)/include -I $(top_srcdir)
 # May be used by toolexeclibdir.
 gcc_version := $(shell @get_g

[PING][PATCH] Add patch for debugging compiler ICEs.

2014-08-12 Thread Maxim Ostapenko

Ping.

-Maxim
 Original Message 
Subject:[PATCH] Add patch for debugging compiler ICEs.
Date:   Mon, 04 Aug 2014 21:03:22 +0400
From:   Maxim Ostapenko 
To: GCC Patches 
CC: 	Jeff Law , Jakub Jelinek , 
tsaund...@mozilla.com, Yury Gribov , Slava 
Garbuzov 



On 08/04/2014 09:03 PM, Maxim Ostapenko wrote:

Hi,

A years ago there was a discussion 
(https://gcc.gnu.org/ml/gcc-patches/2004-01/msg02437.html) about 
debugging compiler ICEs that resulted in a patch from Jakub, which 
dumps useful information into temporary file, but for some reasons 
this patch wasn't applied to trunk.


This is the resurrected patch with added GCC version information into 
generated repro file.


I've updated the patch that I've posted earlier 
(https://gcc.gnu.org/ml/gcc-patches/2014-07/msg01649.html ) according 
to recent upstream discussion 
(https://gcc.gnu.org/ml/gcc-patches/2014-08/msg00020.html).


The debugging functionality is disabled by default and can be enabled 
with adding -freport-bug into compile options. It can be also enabled 
by default with

--with-spec during GCC build.

There are several directions in which this can be improved e.g:

1) more user-friendly ways to report bugs (autosubmitting to Bugzilla, 
etc.)


2) generate repro in case of segfault.

but having basic functionality (autogenerating reprocase in temprorary 
file) already seems quite useful.


-Maxim







Fwd: [PATCH] Add patch for debugging compiler ICEs.

2014-08-19 Thread Maxim Ostapenko

Ping.

-Maxim
 Original Message 
Subject:[PATCH] Add patch for debugging compiler ICEs.
Date:   Mon, 04 Aug 2014 21:03:22 +0400
From:   Maxim Ostapenko 
To: GCC Patches 
CC: 	Jeff Law , Jakub Jelinek , 
tsaund...@mozilla.com, Yury Gribov , Slava 
Garbuzov 




Hi,

A years ago there was a discussion
(https://gcc.gnu.org/ml/gcc-patches/2004-01/msg02437.html) about
debugging compiler ICEs that resulted in a patch from Jakub, which dumps
useful information into temporary file, but for some reasons this patch
wasn't applied to trunk.

This is the resurrected patch with added GCC version information into
generated repro file.

I've updated the patch that I've posted earlier
(https://gcc.gnu.org/ml/gcc-patches/2014-07/msg01649.html ) according to
recent upstream discussion
(https://gcc.gnu.org/ml/gcc-patches/2014-08/msg00020.html).

The debugging functionality is disabled by default and can be enabled
with adding -freport-bug into compile options. It can be also enabled by
default with
--with-spec during GCC build.

There are several directions in which this can be improved e.g:

1) more user-friendly ways to report bugs (autosubmitting to Bugzilla, etc.)

2) generate repro in case of segfault.

but having basic functionality (autogenerating reprocase in temprorary
file) already seems quite useful.

-Maxim



2014-08-04  Jakub Jelinek  
	  Max Ostapenko  

	* common.opt: New option.
	* doc/invoke.texi: Describe new option.
	* diagnostic.c (diagnostic_action_after_output): Exit with
	ICE_EXIT_CODE instead of FATAL_EXIT_CODE.
	* gcc.c (execute): Don't free first string early, but at the end
	of the function.  Call retry_ice if compiler exited with
	ICE_EXIT_CODE.
	(main): Factor out common code.
	(print_configuration): New function.
	(try_fork): Likewise.
	(redirect_stdout_stderr): Likewise.
	(files_equal_p): Likewise.
	(check_repro): Likewise.
	(run_attempt): Likewise.
	(do_report_bug): Likewise.
	(append_text): Likewise.
	(try_generate_repro): Likewise

diff --git a/gcc/common.opt b/gcc/common.opt
index 0c4f86b..aa79250 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -1120,6 +1120,11 @@ fdump-noaddr
 Common Report Var(flag_dump_noaddr)
 Suppress output of addresses in debugging dumps
 
+freport-bug
+Common Driver Var(flag_report_bug)
+Collect and dump debug information into temporary file if ICE in C/C++
+compiler occured.
+
 fdump-passes
 Common Var(flag_dump_passes) Init(0)
 Dump optimization passes
diff --git a/gcc/diagnostic.c b/gcc/diagnostic.c
index 0cc7593..67b8c5b 100644
--- a/gcc/diagnostic.c
+++ b/gcc/diagnostic.c
@@ -492,7 +492,7 @@ diagnostic_action_after_output (diagnostic_context *context,
 	real_abort ();
   diagnostic_finish (context);
   fnotice (stderr, "compilation terminated.\n");
-  exit (FATAL_EXIT_CODE);
+  exit (ICE_EXIT_CODE);
 
 default:
   gcc_unreachable ();
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 4f327df..dafb573 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -6271,6 +6271,11 @@ feasible to use diff on debugging dumps for compiler invocations with
 different compiler binaries and/or different
 text / bss / data / heap / stack / dso start locations.
 
+@item -freport-bug
+@opindex freport-bug
+Collect and dump debug information into temporary file if ICE in C/C++
+compiler occured.
+
 @item -fdump-unnumbered
 @opindex fdump-unnumbered
 When doing debugging dumps, suppress instruction numbers and address output.
diff --git a/gcc/gcc.c b/gcc/gcc.c
index 44d0416..f7a56d1 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -43,6 +43,13 @@ compilation is specified by a string called a "spec".  */
 #include "params.h"
 #include "vec.h"
 #include "filenames.h"
+#ifdef HAVE_UNISTD_H
+#include 
+#endif
+
+#if !(defined (__MSDOS__) || defined (OS2) || defined (VMS))
+#define RETRY_ICE_SUPPORTED
+#endif
 
 /* By default there is no special suffix for target executables.  */
 /* FIXME: when autoconf is fixed, remove the host check - dj */
@@ -253,6 +260,9 @@ static void init_gcc_specs (struct obstack *, const char *, const char *,
 static const char *convert_filename (const char *, int, int);
 #endif
 
+#ifdef RETRY_ICE_SUPPORTED
+static void try_generate_repro (const char *prog, const char **argv);
+#endif
 static const char *getenv_spec_function (int, const char **);
 static const char *if_exists_spec_function (int, const char **);
 static const char *if_exists_else_spec_function (int, const char **);
@@ -2849,7 +2859,7 @@ execute (void)
 	}
 	}
 
-  if (string != commands[i].prog)
+  if (i && string != commands[i].prog)
 	free (CONST_CAST (char *, string));
 }
 
@@ -2902,6 +2912,17 @@ execute (void)
 	else if (WIFEXITED (status)
 		 && WEXITSTATUS (status) >= MIN_FATAL_STATUS)
 	  {
+#ifdef RETRY_ICE_SUPPORTED
+	/* For ICEs in cc1, cc1obj, cc1plus see if it is
+	   reproducible or not.  */
+

[PATCH] Fix environment variables restoring in GCC testsuite.

2014-08-22 Thread Maxim Ostapenko

Hi,

When testing, I've noticed, that Asan-bootstrapped GCC should be 
executed with ASAN_OPTIONS=detect_leaks=0 because of memory leaks in 
GCC, reported by Leak Sanitizer.


When I ran Asan test on Asan-bootstrapped GCC, some of them fail with 
memory leaks into GCC, even if Lsan is disabled. This caused by slightly 
wrong logic in saving/restoring env variables functionality in 
gcc-dg.exp (some tests override ASAN_OPTIONS and this env variable isn't 
restored correcty).


This tiny patch seems to fix the issue.

Tested on x86_64-pc-linux-gnu.

Ok to commit?

-Maxim
gcc/testsuite/ChangeLog:

2014-08-22  Max Ostapenko  

	* lib/gcc-dg.exp: Change pattern.

diff --git a/gcc/testsuite/lib/gcc-dg.exp b/gcc/testsuite/lib/gcc-dg.exp
index 3390caa..d438c05 100644
--- a/gcc/testsuite/lib/gcc-dg.exp
+++ b/gcc/testsuite/lib/gcc-dg.exp
@@ -295,8 +295,8 @@ proc set-target-env-var { } {
 foreach env_var $set_target_env_var {
 	set var [lindex $env_var 0]
 	set value [lindex $env_var 1]
-	if [info exists env($var)] {
-	lappend saved_target_env_var [list $var 1 $env($var)]
+	if [info exists ::env($var)] {
+	lappend saved_target_env_var [list $var 1 $::env($var)]
 	} else {
 	lappend saved_target_env_var [list $var 0]
 	}


[PATCH] Fix libbacktrace and libiberty tests fail on sanitized GCC due to wrong link options.

2014-08-25 Thread Maxim Ostapenko

Hi,

When I ran Asan tests under Asan-bootstrapped GCC 5.0, I've noted, that 
tests for libiberty and libbacktrace fail to link with sanitized 
libbacktrace.a and libiberty.a because of missing -static-libasan 
-fsanitize=address linker flags.


This patch adds necessary flags to provide a linkage of these tests in 
bootstrap-asan case.


I've checked that regression tests pass with disabled bootstrap, normal 
bootstrap (stage1, stage3) and Asan-bootstrap (stage 1, stage3) on 
x86_64-pc-linux-gnu.


Does the patch look sane?

-Maxim
libiberty/ChangeLog:

2014-08-25  Max Ostapenko  

	* testsuite/Makefile.in(LIBCFLAGS): Add LDFLAGS.

ChangeLog:

2014-08-25  Max Ostapenko  

	* Makefile.in (EXTRA_HOST_EXPORTS): New variables.
	(EXTRA_BOOTSTRAP_FLAGS): Likewise.
	(check-libiberty): Add EXTRA_HOST_EXPORTS and EXTRA_BOOTSTRAP_FLAGS.
	(check-libbacktrace): Likewise.

diff --git a/Makefile.in b/Makefile.in
index add8cf6..93d48b8 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -20541,8 +20541,9 @@ check-libbacktrace:
 	@r=`${PWD_COMMAND}`; export r; \
 	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
 	$(HOST_EXPORTS) \
+	$(EXTRA_HOST_EXPORTS) \
 	(cd $(HOST_SUBDIR)/libbacktrace && \
-	  $(MAKE) $(FLAGS_TO_PASS)  check)
+	  $(MAKE) $(FLAGS_TO_PASS) $(EXTRA_BOOTSTRAP_FLAGS)  check)
 
 @endif libbacktrace
 
@@ -23597,6 +23598,13 @@ clean-stagefeedback-libiberty:
 @endif libiberty-bootstrap
 
 
+@if gcc-bootstrap
+EXTRA_HOST_EXPORTS = if [ $(current_stage) != stage1 ]; then \
+	  $(POSTSTAGE1_HOST_EXPORTS) \
+	 fi ;
+
+EXTRA_BOOTSTRAP_FLAGS = CC="$$CC" CXX="$$CXX" LDFLAGS="$$LDFLAGS"
+@endif gcc-bootstrap
 
 
 
@@ -23610,8 +23618,9 @@ check-libiberty:
 	@r=`${PWD_COMMAND}`; export r; \
 	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
 	$(HOST_EXPORTS) \
+	$(EXTRA_HOST_EXPORTS) \
 	(cd $(HOST_SUBDIR)/libiberty && \
-	  $(MAKE) $(FLAGS_TO_PASS)  check)
+	  $(MAKE) $(FLAGS_TO_PASS) $(EXTRA_BOOTSTRAP_FLAGS)  check)
 
 @endif libiberty
 
diff --git a/libiberty/testsuite/Makefile.in b/libiberty/testsuite/Makefile.in
index d23c09c..ef693c2 100644
--- a/libiberty/testsuite/Makefile.in
+++ b/libiberty/testsuite/Makefile.in
@@ -33,7 +33,7 @@ SHELL = @SHELL@
 
 CC = @CC@
 CFLAGS = @CFLAGS@
-LIBCFLAGS = $(CFLAGS)
+LIBCFLAGS = $(CFLAGS) $(LDFLAGS)
 
 # Multilib support variables.
 MULTISRCTOP =


[Ping v2][PATCH] Add patch for debugging compiler ICEs.

2014-08-28 Thread Maxim Ostapenko

Ping. Add Joseph S. Myers as driver maintainer.

-Maxim
 Original Message 
Subject:Fwd: [PATCH] Add patch for debugging compiler ICEs.
Date:   Tue, 19 Aug 2014 17:57:51 +0400
From:   Maxim Ostapenko 
To: Jeff Law , GCC Patches 
CC: 	tsaund...@mozilla.com, Yury Gribov , Slava 
Garbuzov , Maxim Ostapenko 




Ping.

-Maxim
 Original Message 
Subject:[PATCH] Add patch for debugging compiler ICEs.
Date:   Mon, 04 Aug 2014 21:03:22 +0400
From:   Maxim Ostapenko 
To: GCC Patches 
CC: Jeff Law , Jakub Jelinek ,
tsaund...@mozilla.com, Yury Gribov , Slava
Garbuzov 



Hi,

A years ago there was a discussion
(https://gcc.gnu.org/ml/gcc-patches/2004-01/msg02437.html) about
debugging compiler ICEs that resulted in a patch from Jakub, which dumps
useful information into temporary file, but for some reasons this patch
wasn't applied to trunk.

This is the resurrected patch with added GCC version information into
generated repro file.

I've updated the patch that I've posted earlier
(https://gcc.gnu.org/ml/gcc-patches/2014-07/msg01649.html ) according to
recent upstream discussion
(https://gcc.gnu.org/ml/gcc-patches/2014-08/msg00020.html).

The debugging functionality is disabled by default and can be enabled
with adding -freport-bug into compile options. It can be also enabled by
default with
--with-spec during GCC build.

There are several directions in which this can be improved e.g:

1) more user-friendly ways to report bugs (autosubmitting to Bugzilla, etc.)

2) generate repro in case of segfault.

but having basic functionality (autogenerating reprocase in temprorary
file) already seems quite useful.

-Maxim






2014-08-04  Jakub Jelinek  
	  Max Ostapenko  

	* common.opt: New option.
	* doc/invoke.texi: Describe new option.
	* diagnostic.c (diagnostic_action_after_output): Exit with
	ICE_EXIT_CODE instead of FATAL_EXIT_CODE.
	* gcc.c (execute): Don't free first string early, but at the end
	of the function.  Call retry_ice if compiler exited with
	ICE_EXIT_CODE.
	(main): Factor out common code.
	(print_configuration): New function.
	(try_fork): Likewise.
	(redirect_stdout_stderr): Likewise.
	(files_equal_p): Likewise.
	(check_repro): Likewise.
	(run_attempt): Likewise.
	(do_report_bug): Likewise.
	(append_text): Likewise.
	(try_generate_repro): Likewise

diff --git a/gcc/common.opt b/gcc/common.opt
index 0c4f86b..aa79250 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -1120,6 +1120,11 @@ fdump-noaddr
 Common Report Var(flag_dump_noaddr)
 Suppress output of addresses in debugging dumps
 
+freport-bug
+Common Driver Var(flag_report_bug)
+Collect and dump debug information into temporary file if ICE in C/C++
+compiler occured.
+
 fdump-passes
 Common Var(flag_dump_passes) Init(0)
 Dump optimization passes
diff --git a/gcc/diagnostic.c b/gcc/diagnostic.c
index 0cc7593..67b8c5b 100644
--- a/gcc/diagnostic.c
+++ b/gcc/diagnostic.c
@@ -492,7 +492,7 @@ diagnostic_action_after_output (diagnostic_context *context,
 	real_abort ();
   diagnostic_finish (context);
   fnotice (stderr, "compilation terminated.\n");
-  exit (FATAL_EXIT_CODE);
+  exit (ICE_EXIT_CODE);
 
 default:
   gcc_unreachable ();
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 4f327df..dafb573 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -6271,6 +6271,11 @@ feasible to use diff on debugging dumps for compiler invocations with
 different compiler binaries and/or different
 text / bss / data / heap / stack / dso start locations.
 
+@item -freport-bug
+@opindex freport-bug
+Collect and dump debug information into temporary file if ICE in C/C++
+compiler occured.
+
 @item -fdump-unnumbered
 @opindex fdump-unnumbered
 When doing debugging dumps, suppress instruction numbers and address output.
diff --git a/gcc/gcc.c b/gcc/gcc.c
index 44d0416..f7a56d1 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -43,6 +43,13 @@ compilation is specified by a string called a "spec".  */
 #include "params.h"
 #include "vec.h"
 #include "filenames.h"
+#ifdef HAVE_UNISTD_H
+#include 
+#endif
+
+#if !(defined (__MSDOS__) || defined (OS2) || defined (VMS))
+#define RETRY_ICE_SUPPORTED
+#endif
 
 /* By default there is no special suffix for target executables.  */
 /* FIXME: when autoconf is fixed, remove the host check - dj */
@@ -253,6 +260,9 @@ static void init_gcc_specs (struct obstack *, const char *, const char *,
 static const char *convert_filename (const char *, int, int);
 #endif
 
+#ifdef RETRY_ICE_SUPPORTED
+static void try_generate_repro (const char *prog, const char **argv);
+#endif
 static const char *getenv_spec_function (int, const char **);
 static const char *if_exists_spec_function (int, const char **);
 static const char *if_exists_else_spec_function (int, const char **);
@@ -2849,7 +2859,7 @@ execute (void)
 	}
 	}
 
-  if (string != commands[i].prog)
+  i

Re: [PATCH] Fix libbacktrace and libiberty tests fail on sanitized GCC due to wrong link options.

2014-09-01 Thread Maxim Ostapenko


On 08/25/2014 07:21 PM, Bernhard Reutner-Fischer wrote:

On 25 August 2014 16:23:54 CEST, Yury Gribov  wrote:

On 08/25/2014 11:04 AM, Maxim Ostapenko wrote:

This patch adds necessary flags to provide a linkage of these tests

in

bootstrap-asan case.

I think you'll want to modify Makefile.def and Makefile.tpl because
Makefile is generated from them.

Thanks, got it. Here the updated version of previous patch.

Does the patch look sane now?


Sounds like this would fix https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56781

Thanks,



-Maxim
libiberty/ChangeLog:

2014-09-01  Max Ostapenko  

	* testsuite/Makefile.in(LIBCFLAGS): Add LDFLAGS.

ChangeLog:

2014-09-01  Max Ostapenko  

	* Makefile.tpl (EXTRA_HOST_EXPORTS): New variables.
	(EXTRA_BOOTSTRAP_FLAGS): Likewise.
	(check-[+module+]): Add EXTRA_HOST_EXPORTS and EXTRA_BOOTSTRAP_FLAGS.
	* Makefile.in: Regenerate.


diff --git a/Makefile.in b/Makefile.in
index add8cf6..b0917e3 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -830,6 +830,14 @@ POSTSTAGE1_FLAGS_TO_PASS = \
 	HOST_LIBS="$${HOST_LIBS}" \
 	"`echo 'ADAFLAGS=$(BOOT_ADAFLAGS)' | sed -e s'/[^=][^=]*=$$/XFOO=/'`"
 
+@if gcc-bootstrap
+EXTRA_HOST_EXPORTS = if [ $(current_stage) != stage1 ]; then \
+		   $(POSTSTAGE1_HOST_EXPORTS) \
+		 fi ;
+
+EXTRA_BOOTSTRAP_FLAGS = CC="$$CC" CXX="$$CXX" LDFLAGS="$$LDFLAGS"
+@endif gcc-bootstrap
+
 # Flags to pass down to makes which are built with the target environment.
 # The double $ decreases the length of the command line; those variables
 # are set in BASE_FLAGS_TO_PASS, and the sub-make will expand them.  The
@@ -3518,9 +3526,9 @@ check-bfd:
 	@: $(MAKE); $(unstage)
 	@r=`${PWD_COMMAND}`; export r; \
 	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
-	$(HOST_EXPORTS) \
+	$(HOST_EXPORTS) $(EXTRA_HOST_EXPORTS) \
 	(cd $(HOST_SUBDIR)/bfd && \
-	  $(MAKE) $(FLAGS_TO_PASS)  check)
+	  $(MAKE) $(FLAGS_TO_PASS)  $(EXTRA_BOOTSTRAP_FLAGS) check)
 
 @endif bfd
 
@@ -4392,9 +4400,9 @@ check-opcodes:
 	@: $(MAKE); $(unstage)
 	@r=`${PWD_COMMAND}`; export r; \
 	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
-	$(HOST_EXPORTS) \
+	$(HOST_EXPORTS) $(EXTRA_HOST_EXPORTS) \
 	(cd $(HOST_SUBDIR)/opcodes && \
-	  $(MAKE) $(FLAGS_TO_PASS)  check)
+	  $(MAKE) $(FLAGS_TO_PASS)  $(EXTRA_BOOTSTRAP_FLAGS) check)
 
 @endif opcodes
 
@@ -5266,9 +5274,9 @@ check-binutils:
 	@: $(MAKE); $(unstage)
 	@r=`${PWD_COMMAND}`; export r; \
 	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
-	$(HOST_EXPORTS) \
+	$(HOST_EXPORTS) $(EXTRA_HOST_EXPORTS) \
 	(cd $(HOST_SUBDIR)/binutils && \
-	  $(MAKE) $(FLAGS_TO_PASS)  check)
+	  $(MAKE) $(FLAGS_TO_PASS)  $(EXTRA_BOOTSTRAP_FLAGS) check)
 
 @endif binutils
 
@@ -5696,9 +5704,9 @@ check-bison:
 	@if [ '$(host)' = '$(target)' ] ; then \
 	  r=`${PWD_COMMAND}`; export r; \
 	  s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
-	  $(HOST_EXPORTS) \
+	  $(HOST_EXPORTS)  \
 	  (cd $(HOST_SUBDIR)/bison && \
-	$(MAKE) $(FLAGS_TO_PASS)  check); \
+	$(MAKE) $(FLAGS_TO_PASS)  check)
 	fi
 
 @endif bison
@@ -6138,7 +6146,7 @@ check-cgen:
 	@: $(MAKE); $(unstage)
 	@r=`${PWD_COMMAND}`; export r; \
 	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
-	$(HOST_EXPORTS) \
+	$(HOST_EXPORTS)  \
 	(cd $(HOST_SUBDIR)/cgen && \
 	  $(MAKE) $(FLAGS_TO_PASS)  check)
 
@@ -6579,7 +6587,7 @@ check-dejagnu:
 	@: $(MAKE); $(unstage)
 	@r=`${PWD_COMMAND}`; export r; \
 	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
-	$(HOST_EXPORTS) \
+	$(HOST_EXPORTS)  \
 	(cd $(HOST_SUBDIR)/dejagnu && \
 	  $(MAKE) $(FLAGS_TO_PASS)  check)
 
@@ -7020,7 +7028,7 @@ check-etc:
 	@: $(MAKE); $(unstage)
 	@r=`${PWD_COMMAND}`; export r; \
 	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
-	$(HOST_EXPORTS) \
+	$(HOST_EXPORTS)  \
 	(cd $(HOST_SUBDIR)/etc && \
 	  $(MAKE) $(FLAGS_TO_PASS)  check)
 
@@ -7463,9 +7471,9 @@ check-fastjar:
 	@if [ '$(host)' = '$(target)' ] ; then \
 	  r=`${PWD_COMMAND}`; export r; \
 	  s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
-	  $(HOST_EXPORTS) \
+	  $(HOST_EXPORTS)  \
 	  (cd $(HOST_SUBDIR)/fastjar && \
-	$(MAKE) $(FLAGS_TO_PASS)  check); \
+	$(MAKE) $(FLAGS_TO_PASS)  check)
 	fi
 
 @endif fastjar
@@ -8351,9 +8359,9 @@ check-fixincludes:
 	@: $(MAKE); $(unstage)
 	@r=`${PWD_COMMAND}`; export r; \
 	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
-	$(HOST_EXPORTS) \
+	$(HOST_EXPORTS) $(EXTRA_HOST_EXPORTS) \
 	(cd $(HOST_SUBDIR)/fixincludes && \
-	  $(MAKE) $(FLAGS_TO_PASS)  check)
+	  $(MAKE) $(FLAGS_TO_PASS)  $(EXTRA_BOOTSTRAP_FLAGS) check)
 
 @endif fixincludes
 
@@ -8766,9 +8774,9 @@ check-flex:
 	@if [ '$(host)' = '$(target)' ] ; then \
 	  r=`${PWD_COMMAND}`; export r; \
 	  s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
-	  $(HOST_EXPORTS) \
+	  $(HOST_EXPORTS)  \
 	  (cd $(HOST_SUBDIR)/flex && \
-	$(MAKE) $(FLAGS_TO_PASS)  check); \
+

Re: [PATCH] Fix libbacktrace and libiberty tests fail on sanitized GCC due to wrong link options.

2014-09-01 Thread Maxim Ostapenko


On 09/01/2014 11:29 AM, Jakub Jelinek wrote:

On Mon, Sep 01, 2014 at 11:19:07AM +0400, Maxim Ostapenko wrote:

libiberty/ChangeLog:

2014-09-01  Max Ostapenko  

* testsuite/Makefile.in(LIBCFLAGS): Add LDFLAGS.

Space before (.

Ugh, sorry.



  # Flags to pass down to makes which are built with the target environment.
  # The double $ decreases the length of the command line; those variables
  # are set in BASE_FLAGS_TO_PASS, and the sub-make will expand them.  The
@@ -3518,9 +3526,9 @@ check-bfd:
@: $(MAKE); $(unstage)
@r=`${PWD_COMMAND}`; export r; \
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
-   $(HOST_EXPORTS) \
+   $(HOST_EXPORTS) $(EXTRA_HOST_EXPORTS) \
(cd $(HOST_SUBDIR)/bfd && \
- $(MAKE) $(FLAGS_TO_PASS)  check)
+ $(MAKE) $(FLAGS_TO_PASS)  $(EXTRA_BOOTSTRAP_FLAGS) check)

I'd put the double space right before check instead of in between
different flags, or use a single space everywhere.
Here the first space appears because extra_make_flags (EXTRA_GCC_FLAGS) 
is empty and autogen replaces this with a space. Removing the second one 
will lead to concatinating of $(EXTRA_GCC_FLAGS) and 
$(EXTRA_BOOTSTRAP_FLAGS). I know, two spaces look ugly, but is there 
more convenient way to avoid this?

@@ -4392,9 +4400,9 @@ check-opcodes:
@: $(MAKE); $(unstage)
@r=`${PWD_COMMAND}`; export r; \
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
-   $(HOST_EXPORTS) \
+   $(HOST_EXPORTS) $(EXTRA_HOST_EXPORTS) \
(cd $(HOST_SUBDIR)/opcodes && \
- $(MAKE) $(FLAGS_TO_PASS)  check)
+ $(MAKE) $(FLAGS_TO_PASS)  $(EXTRA_BOOTSTRAP_FLAGS) check)

Ditto etc.


@@ -6138,7 +6146,7 @@ check-cgen:
@: $(MAKE); $(unstage)
@r=`${PWD_COMMAND}`; export r; \
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
-   $(HOST_EXPORTS) \
+   $(HOST_EXPORTS)  \

Why?
This is pretty the same. For all libs, that wouldn't be bootstrapped, 
autogen inserts a space instead of $(EXTRA_HOST_EXPORTS).


Perhaps I should always insert $(EXTRA_HOST_EXPORTS) and 
$(EXTRA_BOOTSTRAP_FLAGS) with empty/nonempty values instead of tracking 
libraries, that would/wouldn't be bootstrapped?


-Maxim

Jakub





[PING][PATCH] Fix environment variables restoring in GCC testsuite.

2014-09-01 Thread Maxim Ostapenko

Ping.

-Maxim
 Original Message 
Subject:[PATCH] Fix environment variables restoring in GCC testsuite.
Date:   Fri, 22 Aug 2014 14:39:16 +0400
From:   Maxim Ostapenko 
To: GCC Patches 
CC: 	Yury Gribov , Slava Garbuzov 





Hi,

When testing, I've noticed, that Asan-bootstrapped GCC should be
executed with ASAN_OPTIONS=detect_leaks=0 because of memory leaks in
GCC, reported by Leak Sanitizer.

When I ran Asan test on Asan-bootstrapped GCC, some of them fail with
memory leaks into GCC, even if Lsan is disabled. This caused by slightly
wrong logic in saving/restoring env variables functionality in
gcc-dg.exp (some tests override ASAN_OPTIONS and this env variable isn't
restored correcty).

This tiny patch seems to fix the issue.

Tested on x86_64-pc-linux-gnu.

Ok to commit?

-Maxim



gcc/testsuite/ChangeLog:

2014-09-01  Max Ostapenko  

	* lib/gcc-dg.exp: Change pattern.

diff --git a/gcc/testsuite/lib/gcc-dg.exp b/gcc/testsuite/lib/gcc-dg.exp
index 3390caa..d438c05 100644
--- a/gcc/testsuite/lib/gcc-dg.exp
+++ b/gcc/testsuite/lib/gcc-dg.exp
@@ -295,8 +295,8 @@ proc set-target-env-var { } {
 foreach env_var $set_target_env_var {
 	set var [lindex $env_var 0]
 	set value [lindex $env_var 1]
-	if [info exists env($var)] {
-	lappend saved_target_env_var [list $var 1 $env($var)]
+	if [info exists ::env($var)] {
+	lappend saved_target_env_var [list $var 1 $::env($var)]
 	} else {
 	lappend saved_target_env_var [list $var 0]
 	}


[Ping v3][PATCH] Add patch for debugging compiler ICEs.

2014-09-05 Thread Maxim Ostapenko

Ping.

-Maxim
On 08/28/2014 11:31 AM, Maxim Ostapenko wrote:

Ping. Add Joseph S. Myers as driver maintainer.

-Maxim
 Original Message 
Subject: Fwd: [PATCH] Add patch for debugging compiler ICEs.
Date: Tue, 19 Aug 2014 17:57:51 +0400
From: Maxim Ostapenko 
To: Jeff Law , GCC Patches 
CC: tsaund...@mozilla.com, Yury Gribov , 
Slava Garbuzov , Maxim Ostapenko 





Ping.

-Maxim
 Original Message 
Subject: [PATCH] Add patch for debugging compiler ICEs.
Date: Mon, 04 Aug 2014 21:03:22 +0400
From: Maxim Ostapenko 
To: GCC Patches 
CC: Jeff Law , Jakub Jelinek ,
tsaund...@mozilla.com, Yury Gribov , Slava
Garbuzov 



Hi,

A years ago there was a discussion
(https://gcc.gnu.org/ml/gcc-patches/2004-01/msg02437.html) about
debugging compiler ICEs that resulted in a patch from Jakub, which dumps
useful information into temporary file, but for some reasons this patch
wasn't applied to trunk.

This is the resurrected patch with added GCC version information into
generated repro file.

I've updated the patch that I've posted earlier
(https://gcc.gnu.org/ml/gcc-patches/2014-07/msg01649.html ) according to
recent upstream discussion
(https://gcc.gnu.org/ml/gcc-patches/2014-08/msg00020.html).

The debugging functionality is disabled by default and can be enabled
with adding -freport-bug into compile options. It can be also enabled by
default with
--with-spec during GCC build.

There are several directions in which this can be improved e.g:

1) more user-friendly ways to report bugs (autosubmitting to Bugzilla, 
etc.)


2) generate repro in case of segfault.

but having basic functionality (autogenerating reprocase in temprorary
file) already seems quite useful.

-Maxim








2014-08-04  Jakub Jelinek  
	  Max Ostapenko  

	* common.opt: New option.
	* doc/invoke.texi: Describe new option.
	* diagnostic.c (diagnostic_action_after_output): Exit with
	ICE_EXIT_CODE instead of FATAL_EXIT_CODE.
	* gcc.c (execute): Don't free first string early, but at the end
	of the function.  Call retry_ice if compiler exited with
	ICE_EXIT_CODE.
	(main): Factor out common code.
	(print_configuration): New function.
	(try_fork): Likewise.
	(redirect_stdout_stderr): Likewise.
	(files_equal_p): Likewise.
	(check_repro): Likewise.
	(run_attempt): Likewise.
	(do_report_bug): Likewise.
	(append_text): Likewise.
	(try_generate_repro): Likewise

diff --git a/gcc/common.opt b/gcc/common.opt
index f7021102..1133e61 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -1120,6 +1120,11 @@ fdump-noaddr
 Common Report Var(flag_dump_noaddr)
 Suppress output of addresses in debugging dumps
 
+freport-bug
+Common Driver Var(flag_report_bug)
+Collect and dump debug information into temporary file if ICE in C/C++
+compiler occured.
+
 fdump-passes
 Common Var(flag_dump_passes) Init(0)
 Dump optimization passes
diff --git a/gcc/diagnostic.c b/gcc/diagnostic.c
index 73666d6..60ed607 100644
--- a/gcc/diagnostic.c
+++ b/gcc/diagnostic.c
@@ -494,7 +494,7 @@ diagnostic_action_after_output (diagnostic_context *context,
 	real_abort ();
   diagnostic_finish (context);
   fnotice (stderr, "compilation terminated.\n");
-  exit (FATAL_EXIT_CODE);
+  exit (ICE_EXIT_CODE);
 
 default:
   gcc_unreachable ();
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index d15d4a9..f41a1d8 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -6316,6 +6316,11 @@ feasible to use diff on debugging dumps for compiler invocations with
 different compiler binaries and/or different
 text / bss / data / heap / stack / dso start locations.
 
+@item -freport-bug
+@opindex freport-bug
+Collect and dump debug information into temporary file if ICE in C/C++
+compiler occured.
+
 @item -fdump-unnumbered
 @opindex fdump-unnumbered
 When doing debugging dumps, suppress instruction numbers and address output.
diff --git a/gcc/gcc.c b/gcc/gcc.c
index 44d0416..e0c403d 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -43,6 +43,13 @@ compilation is specified by a string called a "spec".  */
 #include "params.h"
 #include "vec.h"
 #include "filenames.h"
+#ifdef HAVE_UNISTD_H
+#include 
+#endif
+
+#if !(defined (__MSDOS__) || defined (OS2) || defined (VMS))
+#define RETRY_ICE_SUPPORTED
+#endif
 
 /* By default there is no special suffix for target executables.  */
 /* FIXME: when autoconf is fixed, remove the host check - dj */
@@ -253,6 +260,9 @@ static void init_gcc_specs (struct obstack *, const char *, const char *,
 static const char *convert_filename (const char *, int, int);
 #endif
 
+#ifdef RETRY_ICE_SUPPORTED
+static void try_generate_repro (const char *prog, const char **argv);
+#endif
 static const char *getenv_spec_function (int, const char **);
 static const char *if_exists_spec_function (int, const char **);
 static const char *if_exists_else_spec_function (int, const char **);
@@ -2849,7 +2859,7 @@ execute (v

[Ping][PATCH] Fix libbacktrace and libiberty tests fail on sanitized GCC due to wrong link options.

2014-09-08 Thread Maxim Ostapenko

Ping.


 Original Message 
Subject: 	Re: [PATCH] Fix libbacktrace and libiberty tests fail on 
sanitized GCC due to wrong link options.

Date:   Mon, 01 Sep 2014 12:33:09 +0400
From:   Maxim Ostapenko 
To: Jakub Jelinek 
CC: 	Bernhard Reutner-Fischer , Yury Gribov 
, GCC Patches , Slava 
Garbuzov 




On 09/01/2014 11:29 AM, Jakub Jelinek wrote:

On Mon, Sep 01, 2014 at 11:19:07AM +0400, Maxim Ostapenko wrote:

libiberty/ChangeLog:

2014-09-01  Max Ostapenko  

* testsuite/Makefile.in(LIBCFLAGS): Add LDFLAGS.

Space before (.


Ugh, sorry.




  # Flags to pass down to makes which are built with the target environment.
  # The double $ decreases the length of the command line; those variables
  # are set in BASE_FLAGS_TO_PASS, and the sub-make will expand them.  The
@@ -3518,9 +3526,9 @@ check-bfd:
@: $(MAKE); $(unstage)
@r=`${PWD_COMMAND}`; export r; \
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
-   $(HOST_EXPORTS) \
+   $(HOST_EXPORTS) $(EXTRA_HOST_EXPORTS) \
(cd $(HOST_SUBDIR)/bfd && \
- $(MAKE) $(FLAGS_TO_PASS)  check)
+ $(MAKE) $(FLAGS_TO_PASS)  $(EXTRA_BOOTSTRAP_FLAGS) check)

I'd put the double space right before check instead of in between
different flags, or use a single space everywhere.


Here the first space appears because extra_make_flags (EXTRA_GCC_FLAGS)
is empty and autogen replaces this with a space. Removing the second one
will lead to concatinating of $(EXTRA_GCC_FLAGS) and
$(EXTRA_BOOTSTRAP_FLAGS). I know, two spaces look ugly, but is there
more convenient way to avoid this?


@@ -4392,9 +4400,9 @@ check-opcodes:
@: $(MAKE); $(unstage)
@r=`${PWD_COMMAND}`; export r; \
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
-   $(HOST_EXPORTS) \
+   $(HOST_EXPORTS) $(EXTRA_HOST_EXPORTS) \
(cd $(HOST_SUBDIR)/opcodes && \
- $(MAKE) $(FLAGS_TO_PASS)  check)
+ $(MAKE) $(FLAGS_TO_PASS)  $(EXTRA_BOOTSTRAP_FLAGS) check)

Ditto etc.


@@ -6138,7 +6146,7 @@ check-cgen:
@: $(MAKE); $(unstage)
@r=`${PWD_COMMAND}`; export r; \
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
-   $(HOST_EXPORTS) \
+   $(HOST_EXPORTS)  \

Why?

This is pretty the same. For all libs, that wouldn't be bootstrapped,
autogen inserts a space instead of $(EXTRA_HOST_EXPORTS).

Perhaps I should always insert $(EXTRA_HOST_EXPORTS) and
$(EXTRA_BOOTSTRAP_FLAGS) with empty/nonempty values instead of tracking
libraries, that would/wouldn't be bootstrapped?

-Maxim

Jakub





libiberty/ChangeLog:

2014-09-01  Max Ostapenko  

	* testsuite/Makefile.in (LIBCFLAGS): Add LDFLAGS.

ChangeLog:

2014-09-01  Max Ostapenko  

	* Makefile.tpl (EXTRA_HOST_EXPORTS): New variables.
	(EXTRA_BOOTSTRAP_FLAGS): Likewise.
	(check-[+module+]): Add EXTRA_HOST_EXPORTS and EXTRA_BOOTSTRAP_FLAGS.
	* Makefile.in: Regenerate.


diff --git a/Makefile.in b/Makefile.in
index add8cf6..b0917e3 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -830,6 +830,14 @@ POSTSTAGE1_FLAGS_TO_PASS = \
 	HOST_LIBS="$${HOST_LIBS}" \
 	"`echo 'ADAFLAGS=$(BOOT_ADAFLAGS)' | sed -e s'/[^=][^=]*=$$/XFOO=/'`"
 
+@if gcc-bootstrap
+EXTRA_HOST_EXPORTS = if [ $(current_stage) != stage1 ]; then \
+		   $(POSTSTAGE1_HOST_EXPORTS) \
+		 fi ;
+
+EXTRA_BOOTSTRAP_FLAGS = CC="$$CC" CXX="$$CXX" LDFLAGS="$$LDFLAGS"
+@endif gcc-bootstrap
+
 # Flags to pass down to makes which are built with the target environment.
 # The double $ decreases the length of the command line; those variables
 # are set in BASE_FLAGS_TO_PASS, and the sub-make will expand them.  The
@@ -3518,9 +3526,9 @@ check-bfd:
 	@: $(MAKE); $(unstage)
 	@r=`${PWD_COMMAND}`; export r; \
 	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
-	$(HOST_EXPORTS) \
+	$(HOST_EXPORTS) $(EXTRA_HOST_EXPORTS) \
 	(cd $(HOST_SUBDIR)/bfd && \
-	  $(MAKE) $(FLAGS_TO_PASS)  check)
+	  $(MAKE) $(FLAGS_TO_PASS)  $(EXTRA_BOOTSTRAP_FLAGS) check)
 
 @endif bfd
 
@@ -4392,9 +4400,9 @@ check-opcodes:
 	@: $(MAKE); $(unstage)
 	@r=`${PWD_COMMAND}`; export r; \
 	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
-	$(HOST_EXPORTS) \
+	$(HOST_EXPORTS) $(EXTRA_HOST_EXPORTS) \
 	(cd $(HOST_SUBDIR)/opcodes && \
-	  $(MAKE) $(FLAGS_TO_PASS)  check)
+	  $(MAKE) $(FLAGS_TO_PASS)  $(EXTRA_BOOTSTRAP_FLAGS) check)
 
 @endif opcodes
 
@@ -5266,9 +5274,9 @@ check-binutils:
 	@: $(MAKE); $(unstage)
 	@r=`${PWD_COMMAND}`; export r; \
 	s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
-	$(HOST_EXPORTS) \
+	$(HOST_EXPORTS) $(EXTRA_HOST_EXPORTS) \
 	(cd $(HOST_SUBDIR)/binutils && \
-	  $(MAKE) $(FLAGS_TO_PASS)  check)
+	  $(MAKE) $(FLAGS_TO_PASS)  $(EXTRA_BOOTSTRAP_FLAGS) check)
 
 @endif binutils
 
@@ -5696,9 +5704,9 @@ check-bison:
 	@if [ '$(host)' = '$(target)' ] ; then \
 	  r=`${PWD_COMMAND}`; export r; \
 	  s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
-	  $

Re: [PATCH] PR58867 ASan and UBSan tests not run for installed testing.

2014-10-08 Thread Maxim Ostapenko

Does it work without restore_ld_library_path in {asan, ubsan, tsan}_finish?

I see two opportunities to fix the issue:

1) Implement a stack of saved contexts.

2) Implement new functions, say {asan, ubsan, 
tsan}_restore_ld_library_path, to be able {asan, ubsan, tsan}_finish 
functions restore context correctly.


What solution is preferable?

-Maxim
On 10/08/2014 01:02 PM, Marcus Shawcroft wrote:

On 1 October 2014 08:09, Maxim Ostapenko
 wrote:

Hi,

some time ago, Andrew wrote a patch that fixes PR58867
(http://patchwork.ozlabs.org/patch/286866/), but for some reasons it
wasn't committed to trunk.

This is resurrected Andrew's patch, extended to support Tsan testsuite.

Tested on x86_64-pc-linux-gnu, ok to commit?

-Maxim

Hi,

This patch  results in wide spread failures in our bare metal test
runs.  I have not dug into the issue in detail but it appears that the
issue is related to the attempted use of  set_ld_library_path_env_vars
  and restore_ld_library_path_env_vars to save and restore nested
contexts.

Consider ubsan/ubsan.exp:

load_lib gcc-dg.exp
...
dg-init
ubsan_init
...
ubsan_finish

The gcc-dg.exp library load calls set_ld_library_path_env_vars the
first time an initializes GCC_EXEC_PREFIX.
The ubsan_init call makes a further call to
set_ld_library_path_env_vars which has no effect.
The ubsan_finish invokes restore_ld_library_path_env_vars, restoring
the environments as it was prior to the call to dg-init.
Any further test execution has now lost the original initialization of
GCC_EXEC_PREFIX by gcc-dg.exp

It seems to me that either this patch assumes  that the
set/restore_ld_library_path_env foo  is capable of maintaining a stack
of saved contexts... which it is not.

Prior to this patch ubsan_finish did not attempt to call
restore_ld_library_path_env_vars hence the gcc-dg.exp environment
remained in place for subsequent test executions.

Cheers
/Marcus





Re: [PATCH] PR58867 ASan and UBSan tests not run for installed testing.

2014-10-08 Thread Maxim Ostapenko
Hm, as I see, others testsuites such as gfortran.exp, go.exp etc. do not 
call restore_ld_library_path at all. Perhaps we could simply follow this 
way?


Would failing tests still fail if remove restore_ld_library_path from 
{asan, tsan, ubsan}_finish?


On 10/08/2014 03:40 PM, Marcus Shawcroft wrote:

On 8 October 2014 11:10, Maxim Ostapenko
 wrote:

Does it work without restore_ld_library_path in {asan, ubsan, tsan}_finish?

I see two opportunities to fix the issue:

1) Implement a stack of saved contexts.

2) Implement new functions, say {asan, ubsan, tsan}_restore_ld_library_path,
to be able {asan, ubsan, tsan}_finish functions restore context correctly.

What solution is preferable?

Option 1 has the advantage that it places all of the context save and
restore in one place rather than spreading it around the
infrastructure.

Please can we revert this patch while a correct implementation is being worked?

Cheers
/Marcus



diff --git a/gcc/testsuite/lib/asan-dg.exp b/gcc/testsuite/lib/asan-dg.exp
index 9769138..c98fd3c 100644
--- a/gcc/testsuite/lib/asan-dg.exp
+++ b/gcc/testsuite/lib/asan-dg.exp
@@ -132,7 +132,6 @@ proc asan_finish { args } {
 	unset TEST_ALWAYS_FLAGS
 	}
 }
-restore_ld_library_path_env_vars
 }
 
 # Symbolize lines like
diff --git a/gcc/testsuite/lib/tsan-dg.exp b/gcc/testsuite/lib/tsan-dg.exp
index 54ec404..6f7a4d9 100644
--- a/gcc/testsuite/lib/tsan-dg.exp
+++ b/gcc/testsuite/lib/tsan-dg.exp
@@ -143,5 +143,4 @@ proc tsan_finish { args } {
 } else {
 	unset dg-do-what-default
 }
-restore_ld_library_path_env_vars
 }
diff --git a/gcc/testsuite/lib/ubsan-dg.exp b/gcc/testsuite/lib/ubsan-dg.exp
index 5a7a653..87c460f 100644
--- a/gcc/testsuite/lib/ubsan-dg.exp
+++ b/gcc/testsuite/lib/ubsan-dg.exp
@@ -114,5 +114,4 @@ proc ubsan_finish { args } {
 	unset TEST_ALWAYS_FLAGS
 	}
 }
-restore_ld_library_path_env_vars
 }


Re: [PATCH] PR58867 ASan and UBSan tests not run for installed testing.

2014-10-08 Thread Maxim Ostapenko

Hi Jiong,

I couldn't reproduce tests failures on my box, perhaps I missed 
something. How can I test this?


-Maxim
On 10/08/2014 06:30 PM, Jiong Wang wrote:


On 08/10/14 15:00, Maxim Ostapenko wrote:

Hm, as I see, others testsuites such as gfortran.exp, go.exp etc. do not
call restore_ld_library_path at all. Perhaps we could simply follow this
way?

Would failing tests still fail if remove restore_ld_library_path from
{asan, tsan, ubsan}_finish?

Hi Maxim,

  verified those fails gone away on check-gcc.

  but not sure whether this remove will cause problem on other test 
environments which they are aimed to solve.


-- Jiong



On 10/08/2014 03:40 PM, Marcus Shawcroft wrote:

On 8 October 2014 11:10, Maxim Ostapenko
 wrote:
Does it work without restore_ld_library_path in {asan, ubsan, 
tsan}_finish?


I see two opportunities to fix the issue:

1) Implement a stack of saved contexts.

2) Implement new functions, say {asan, ubsan, 
tsan}_restore_ld_library_path,
to be able {asan, ubsan, tsan}_finish functions restore context 
correctly.


What solution is preferable?

Option 1 has the advantage that it places all of the context save and
restore in one place rather than spreading it around the
infrastructure.

Please can we revert this patch while a correct implementation is 
being worked?


Cheers
/Marcus









[PATCH] Fix GCC tests fail for installed toolchain due to ASan, UBSan and TSan testsuites drop GCC_EXEC_PREFIX.

2014-10-09 Thread Maxim Ostapenko

Hi,

After enabling ASan, TSan and UBSan testsuites for installed toolchain, 
many tests started to fail. This is caused by wrong logic in {asan, 
ubsan, tsan}_finish
functions. Here, restore_ld_library_path is called, that is wrong, 
because it drops some env variables ( GCC_EXEC_PREFIX, LD_LIBRARY_PATH, 
etc) to state that was before gcc-dg.exp initialized testing 
environment, so installed GCC will be confused to find some needed stuff 
later.


Removing restore_ld_library_path from {asan, ubsan, tsan}_finish seems 
to fix the issue.


Tested on x86_64-pc-linux-gnu, ok to commit?

-Maxim
gcc/testsuite/ChangeLog:

2014-10-09  Max Ostapenko  

	* lib/asan-dg.exp (asan_finish): Remove restore_ld_library_path_env_vars.
	* lib/tsan-dg.exp (tsan_finish): Likewise.
	* lib/ubsan-dg.exp (ubsan_finish): Likewise.

diff --git a/gcc/testsuite/lib/asan-dg.exp b/gcc/testsuite/lib/asan-dg.exp
index 9769138..c98fd3c 100644
--- a/gcc/testsuite/lib/asan-dg.exp
+++ b/gcc/testsuite/lib/asan-dg.exp
@@ -132,7 +132,6 @@ proc asan_finish { args } {
 	unset TEST_ALWAYS_FLAGS
 	}
 }
-restore_ld_library_path_env_vars
 }
 
 # Symbolize lines like
diff --git a/gcc/testsuite/lib/tsan-dg.exp b/gcc/testsuite/lib/tsan-dg.exp
index 54ec404..6f7a4d9 100644
--- a/gcc/testsuite/lib/tsan-dg.exp
+++ b/gcc/testsuite/lib/tsan-dg.exp
@@ -143,5 +143,4 @@ proc tsan_finish { args } {
 } else {
 	unset dg-do-what-default
 }
-restore_ld_library_path_env_vars
 }
diff --git a/gcc/testsuite/lib/ubsan-dg.exp b/gcc/testsuite/lib/ubsan-dg.exp
index 5a7a653..87c460f 100644
--- a/gcc/testsuite/lib/ubsan-dg.exp
+++ b/gcc/testsuite/lib/ubsan-dg.exp
@@ -114,5 +114,4 @@ proc ubsan_finish { args } {
 	unset TEST_ALWAYS_FLAGS
 	}
 }
-restore_ld_library_path_env_vars
 }


Re: [PATCH] Fix GCC tests fail for installed toolchain due to ASan, UBSan and TSan testsuites drop GCC_EXEC_PREFIX.

2014-10-10 Thread Maxim Ostapenko

Adding Jakub.

-Maxim
On 10/09/2014 04:34 PM, Maxim Ostapenko wrote:

Hi,

After enabling ASan, TSan and UBSan testsuites for installed 
toolchain, many tests started to fail. This is caused by wrong logic 
in {asan, ubsan, tsan}_finish
functions. Here, restore_ld_library_path is called, that is wrong, 
because it drops some env variables ( GCC_EXEC_PREFIX, 
LD_LIBRARY_PATH, etc) to state that was before gcc-dg.exp initialized 
testing environment, so installed GCC will be confused to find some 
needed stuff later.


Removing restore_ld_library_path from {asan, ubsan, tsan}_finish seems 
to fix the issue.


Tested on x86_64-pc-linux-gnu, ok to commit?

-Maxim


gcc/testsuite/ChangeLog:

2014-10-09  Max Ostapenko  

	* lib/asan-dg.exp (asan_finish): Remove restore_ld_library_path_env_vars.
	* lib/tsan-dg.exp (tsan_finish): Likewise.
	* lib/ubsan-dg.exp (ubsan_finish): Likewise.

diff --git a/gcc/testsuite/lib/asan-dg.exp b/gcc/testsuite/lib/asan-dg.exp
index 9769138..c98fd3c 100644
--- a/gcc/testsuite/lib/asan-dg.exp
+++ b/gcc/testsuite/lib/asan-dg.exp
@@ -132,7 +132,6 @@ proc asan_finish { args } {
 	unset TEST_ALWAYS_FLAGS
 	}
 }
-restore_ld_library_path_env_vars
 }
 
 # Symbolize lines like
diff --git a/gcc/testsuite/lib/tsan-dg.exp b/gcc/testsuite/lib/tsan-dg.exp
index 54ec404..6f7a4d9 100644
--- a/gcc/testsuite/lib/tsan-dg.exp
+++ b/gcc/testsuite/lib/tsan-dg.exp
@@ -143,5 +143,4 @@ proc tsan_finish { args } {
 } else {
 	unset dg-do-what-default
 }
-restore_ld_library_path_env_vars
 }
diff --git a/gcc/testsuite/lib/ubsan-dg.exp b/gcc/testsuite/lib/ubsan-dg.exp
index 5a7a653..87c460f 100644
--- a/gcc/testsuite/lib/ubsan-dg.exp
+++ b/gcc/testsuite/lib/ubsan-dg.exp
@@ -114,5 +114,4 @@ proc ubsan_finish { args } {
 	unset TEST_ALWAYS_FLAGS
 	}
 }
-restore_ld_library_path_env_vars
 }


Re: [PATCH] Fix GCC tests fail for installed toolchain due to ASan, UBSan and TSan testsuites drop GCC_EXEC_PREFIX.

2014-10-10 Thread Maxim Ostapenko


On 10/10/2014 11:30 AM, Jakub Jelinek wrote:

On Fri, Oct 10, 2014 at 11:13:11AM +0400, Maxim Ostapenko wrote:

Adding Jakub.

-Maxim
On 10/09/2014 04:34 PM, Maxim Ostapenko wrote:

Hi,

After enabling ASan, TSan and UBSan testsuites for installed toolchain,
many tests started to fail. This is caused by wrong logic in {asan, ubsan,
tsan}_finish
functions. Here, restore_ld_library_path is called, that is wrong, because
it drops some env variables ( GCC_EXEC_PREFIX, LD_LIBRARY_PATH, etc) to
state that was before gcc-dg.exp initialized testing environment, so
installed GCC will be confused to find some needed stuff later.

Removing restore_ld_library_path from {asan, ubsan, tsan}_finish seems to
fix the issue.

Tested on x86_64-pc-linux-gnu, ok to commit?

-Maxim

gcc/testsuite/ChangeLog:

2014-10-09  Max Ostapenko  

* lib/asan-dg.exp (asan_finish): Remove 
restore_ld_library_path_env_vars.
* lib/tsan-dg.exp (tsan_finish): Likewise.
* lib/ubsan-dg.exp (ubsan_finish): Likewise.

That looks wrong to me, we don't want to keep the libsanitizer paths in
LD_LIBRARY_PATH* after we leave asan.exp etc.

So, perhaps instead save ld_library_path into some global variable
(like {a,t,ub}san_saved_ld_library_path) during {a,t,ub}san_link_flags
before appending there anything, and replace
restore_ld_library_path_env_vars
with
set ld_library_path ${a,t,ub}san_saved_ld_library_path
set_ld_library_path_env_vars
?

Jakub



This works indeed. However, calling set_ld_library_path_env_vars in 
{asan, tsan, ubsan}_finish will lead to updating LD_LIBRARY_PATH_{32, 
64}, LD_RUN_PATH etc. with "$ld_library_path:$orig_ld_{library_path_32, 
library_path_64, run, etc}". Is this fine?


-Maxim
gcc/testsuite/ChangeLog:

2014-10-10  Max Ostapenko  

	* lib/asan-dg.exp (asan_link_flags): Save ld_library_path.
	* lib/tsan-dg.exp (tsan_link_flags): Likewise.
	* lib/ubsan-dg.exp (ubsan_link_flags): Likewise.
	* lib/asan-dg.exp (asan_finish): Remove restore_ld_library_path_env_vars.
	Restore ld_library_path with saved value. Restore LD_LIBRARY_PATH
	related env variables by calling set_ld_library_path_env_vars.
	* lib/tsan-dg.exp (tsan_finish): Likewise.
	* lib/ubsan-dg.exp (ubsan_finish): Likewise.

diff --git a/gcc/testsuite/lib/asan-dg.exp b/gcc/testsuite/lib/asan-dg.exp
index 9769138..4e8b4d6 100644
--- a/gcc/testsuite/lib/asan-dg.exp
+++ b/gcc/testsuite/lib/asan-dg.exp
@@ -47,11 +47,13 @@ proc asan_link_flags { paths } {
 global srcdir
 global ld_library_path
 global shlib_ext
+global asan_saved_library_path
 
 set gccpath ${paths}
 set flags ""
 
 set shlib_ext [get_shlib_extension]
+set asan_saved_library_path $ld_library_path
 
 if { $gccpath != "" } {
   if { [file exists "${gccpath}/libsanitizer/asan/.libs/libasan.a"]
@@ -122,6 +124,8 @@ proc asan_finish { args } {
 global TEST_ALWAYS_FLAGS
 global asan_saved_TEST_ALWAYS_FLAGS
 global asan_saved_ALWAYS_CXXFLAGS
+global asan_saved_library_path
+global ld_library_path
 
 if [info exists asan_saved_ALWAYS_CXXFLAGS ] {
 	set ALWAYS_CXXFLAGS $asan_saved_ALWAYS_CXXFLAGS
@@ -132,7 +136,8 @@ proc asan_finish { args } {
 	unset TEST_ALWAYS_FLAGS
 	}
 }
-restore_ld_library_path_env_vars
+set ld_library_path $asan_saved_library_path
+set_ld_library_path_env_vars
 }
 
 # Symbolize lines like
diff --git a/gcc/testsuite/lib/tsan-dg.exp b/gcc/testsuite/lib/tsan-dg.exp
index 54ec404..77c85ff 100644
--- a/gcc/testsuite/lib/tsan-dg.exp
+++ b/gcc/testsuite/lib/tsan-dg.exp
@@ -32,11 +32,13 @@ proc tsan_link_flags { paths } {
 global srcdir
 global ld_library_path
 global shlib_ext
+global tsan_saved_library_path
 
 set gccpath ${paths}
 set flags ""
 
 set shlib_ext [get_shlib_extension]
+set tsan_saved_library_path $ld_library_path
 
 if { $gccpath != "" } {
   if { [file exists "${gccpath}/libsanitizer/tsan/.libs/libtsan.a"]
@@ -127,6 +129,8 @@ proc tsan_finish { args } {
 global tsan_saved_ALWAYS_CXXFLAGS
 global dg-do-what-default
 global tsan_saved_dg-do-what-default
+global tsan_saved_library_path
+global ld_library_path
 
 if [info exists tsan_saved_ALWAYS_CXXFLAGS ] {
 	set ALWAYS_CXXFLAGS $tsan_saved_ALWAYS_CXXFLAGS
@@ -143,5 +147,6 @@ proc tsan_finish { args } {
 } else {
 	unset dg-do-what-default
 }
-restore_ld_library_path_env_vars
+set ld_library_path $tsan_saved_library_path
+set_ld_library_path_env_vars
 }
diff --git a/gcc/testsuite/lib/ubsan-dg.exp b/gcc/testsuite/lib/ubsan-dg.exp
index 5a7a653..3bfdcc8 100644
--- a/gcc/testsuite/lib/ubsan-dg.exp
+++ b/gcc/testsuite/lib/ubsan-dg.exp
@@ -32,11 +32,13 @@ proc ubsan_link_flags { paths } {
 global srcdir
 global ld_library_path
 global shlib_ext
+global ubsan_saved_library_path
 
 set gccpath ${paths}
 set flags ""
 
 set shlib_e

[PATCH] Don't expand string/memory builtins if ASan is enabled.

2014-10-17 Thread Maxim Ostapenko

Hi,

this patch disables string/memory builtin functions inlining if ASan is 
enabled. As described in my previous post 
(https://gcc.gnu.org/ml/gcc/2014-09/msg00020.html), this allow us to be 
sure that some dangerous builtins (strcpy, stpcpy, etc) will be handled 
correctly. Also, some redundant checks will be removed for builtin 
functions, that are instrumented but later not inlined for some reason.


Patch also changes logic in asan_mem_ref_hash updating. I eliminated 
memory ref access size from hash computing, so all accesses for same 
memory reference have the same hash. Updating of asan_mem_ref_hash 
occurs only if new access size is greater then saved one.


I've provided some performance testing (spec2006 v1.1) on 
x86_64-unknown-linux-gnu and attached results in test.res (sorry for 
this, I couldn't make my Thunderbird make a pretty table).


Regtested / bootstrapped on x86_64-unknown-linux-gnu.

Does this patch look sane?

-Maxim
$ ~/install/master-x86_64/bin/gcc -v
Using built-in specs.
COLLECT_GCC=/home/max/install/master-x86_64/bin/gcc
COLLECT_LTO_WRAPPER=/home/max/install/master-x86_64/libexec/gcc/x86_64-unknown-linux-gnu/5.0.0/lto-wrapper
Target: x86_64-unknown-linux-gnu
Configured with: /home/max/workspace/downloads/gcc/configure --enable-multilib 
--enable-checking --target=x86_64-unknown-linux-gnu 
--host=x86_64-unknown-linux-gnu --build=x86_64-unknown-linux-gnu 
--prefix=/home/max/install/master-x86_64 --disable-bootstrap 
--enable-languages=c,c++
Thread model: posix
gcc version 5.0.0 20141014 (experimental) (GCC)


Compile options:  -O3 -fsanitize=address -static-libasan.


testmaster  nobuiltin  % of slowdown
400.perlbench1044 10500,5747
401.bzip2682  676-0,8798
403.gcc  497  495-0,4024
429.mcf  488  489 0,2049
445.gobmk723  724 0,1383
456.hmmer783  750-4,2146
458.sjeng887  880-0,7892
462.libquantum   330  323-2,1212
464.h264ref  1108 11544,1516
471.omnetpp  545  559 2,5688
473.astar490  480-2,0408
483.xalancbmk411  400-2,6764
433.milc 517  509-1,5474
444.namd 419  419 0,
450.soplex   310  299-3,5484
453.povray   287  276-3,8328
470.lbm  299  306 2,3411
482.sphinx3  777  804 3,4749

Geomean:
master nobuiltin% of increase
540538-0,50

gcc/ChangeLog:

2014-10-17  Max Ostapenko  

	* asan.c (asan_mem_ref_hasher::hash): Remove MEM_REF access size from
	hash value construction. Call iterative_hash_expr instead of explicit
	hash building.
	(asan_mem_ref_hasher::equal): Change condition.
	(has_mem_ref_been_instrumented): Likewise.
	(update_mem_ref_hash_table): Likewise.
	(maybe_update_mem_ref_hash_table): New function.
	(instrument_strlen_call): Removed.
	(instrument_mem_region_access): Likewise.
	(instrument_builtin_call): Call maybe_update_mem_ref_hash_table instead
	of instrument_mem_region_access.
	* builtins.c (is_memory_builtin): New function.
	(expand_builtin): Don't expand string/memory builtin functions if ASan
	is enabled.
	* builtins.def: Add comment.

gcc/testsuite/ChangeLog:

2014-10-17  Max Ostapenko  

	* c-c++-common/asan/no-redundant-instrumentation-1.c: Updated test.
	* c-c++-common/asan/no-redundant-instrumentation-4.c: Likewise.
	* 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/no-redundant-instrumentation-2.c: Removed.
	* c-c++-common/asan/no-redundant-instrumentation-9.c: Likewise.
	* c-c++-common/asan/no-redundant-instrumentation-10.c: New test.
	* c-c++-common/asan/no-redundant-instrumentation-11.c: Likewise.

diff --git a/gcc/asan.c b/gcc/asan.c
index 2a61a82..391f693 100644
--- a/gcc/asan.c
+++ b/gcc/asan.c
@@ -352,10 +352,7 @@ struct asan_mem_ref_hasher
 inline hashval_t
 asan_mem_ref_hasher::hash (const asan_mem_ref *mem_ref)
 {
-  inchash::hash hstate;
-  inchash::add_expr (mem_ref->start, hstate);
-  hstate.add_wide_int (mem_ref->access_size);
-  return hstate.end ();
+  return iterative_hash_expr (mem_ref->start, 0);
 }
 
 /* Compare two memory references.  We accept the length of either
@@ -365,8 +362,7 @@ inline bool
 asan_mem_ref_hasher::equal (const asan_mem_ref *m1,
 			const asan_mem_ref *m2)
 {
-  return (m1->access_size == m2->access_size
-	  && operand_equal_p (m1->start, m2->start, 0));
+  return operand_equal_p (m1->start, m2->start, 0);
 }
 
 static hash_table *asan_mem_ref_ht;
@@ -417,7 +413,8 @@ has_mem_ref_been_instrumented (tree ref, HOST_WIDE_INT access_size)
   asan_mem_ref r;
   asan_mem_ref_init (&r, ref, access_size);
 
-  return (get_mem_ref_hash_table 

[PATCHv2] Don't expand string/memory builtins if ASan is enabled.

2014-10-21 Thread Maxim Ostapenko

Hi,

this is the second version of the patch. Here the major changes from the 
previous one:


1) Added a new intercepted_p parameter in get_mem_refs_of_builtin_call 
to decide whether builtin function should/shouldn't be instrumented.


2) Changed instrument_mem_region_access function. Now, we update 
asan_mem_ref_ht with (base, size_in_bytes), if we can determine access 
size during compile time.


3) Removed ASAN_CHECK_START_INSTRUMENTED and ASAN_CHECK_END_INSTRUMENTED 
from asan_check_flags since we don't instrument base and end of

memory region with access size 1 anymore.

4) Specified builtins that shouldn't be expanded explicitly in 
gcc/builtins.c.


Regtested / bootrapped on x86_64-unknown-linux-gnu.

-Maxim
On 10/17/2014 05:03 PM, Jakub Jelinek wrote:

On Fri, Oct 17, 2014 at 05:01:33PM +0400, Yury Gribov wrote:

On 10/17/2014 04:24 PM, Jakub Jelinek wrote:

+/* Returns TRUE if given FCODE corresponds to string or memory builtin 
function.
+ */
+
+static inline bool
+is_memory_builtin (enum built_in_function fcode)
+{
+  return fcode <= BUILT_IN_STRSTR && fcode >= BUILT_IN_BCMP;

This is too fragile and ugly.
IMHO you should list (supposedly not in a special inline, but directly
where you use it) in a switch all the builtins you don't want to expand.

We already do this for BUILT_IN_ASAN_REPORT_LOAD1 ... BUILT_IN_ASAN_STOREN

I know, but it is still a coherent sent of builtins for very similar
purposes, many of them sorted by increasing size number.


but I agree that this one is more ugly.

The memops builtins are just random bag of them, it is expected many people
will add builtins into that range and outside of that range.

Jakub



gcc/ChangeLog:

2014-10-21  Max Ostapenko  

	* asan.c (asan_mem_ref_hasher::hash): Remove MEM_REF access size from
	hash value construction. Call iterative_hash_expr instead of explicit
	hash building.
	(asan_mem_ref_hasher::equal): Change condition.
	(has_mem_ref_been_instrumented): Likewise.
	(update_mem_ref_hash_table): Likewise.
	(maybe_update_mem_ref_hash_table): New function.
	(instrument_strlen_call): Removed.
	(get_mem_refs_of_builtin_call): Handle new parameter.
	(instrument_builtin_call): Call maybe_update_mem_ref_hash_table instead
	of instrument_mem_region_access if intercepted_p is true.
	(instrument_mem_region_access): Instrument only base with len instead of
	base and end with 1.
	(build_check_stmt): Remove start_instrumented and end_instrumented
	parameters.
	(enum asan_check_flags): Remove ASAN_CHECK_START_INSTRUMENTED and
	ASAN_CHECK_END_INSTRUMENTED. Change ASAN_CHECK_LAST.
	(asan_expand_check_ifn): Remove start_instrumented and end_instrumented.
	* builtins.c (expand_builtin): Don't expand string/memory builtin functions
	that have interceptors in libsanitizer if ASan is enabled.

gcc/testsuite/ChangeLog:

2014-10-21  Max Ostapenko  

	* c-c++-common/asan/no-redundant-instrumentation-1.c: Updated test.
	* c-c++-common/asan/no-redundant-instrumentation-4.c: Likewise.
	* 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/no-redundant-instrumentation-2.c: Removed.
	* c-c++-common/asan/no-redundant-instrumentation-9.c: Likewise.
	* c-c++-common/asan/no-redundant-instrumentation-10.c: New test.
	* c-c++-common/asan/no-redundant-instrumentation-11.c: Likewise.


diff --git a/gcc/asan.c b/gcc/asan.c
index 2a61a82..a9eb9aa 100644
--- a/gcc/asan.c
+++ b/gcc/asan.c
@@ -253,9 +253,7 @@ enum asan_check_flags
   ASAN_CHECK_STORE = 1 << 0,
   ASAN_CHECK_SCALAR_ACCESS = 1 << 1,
   ASAN_CHECK_NON_ZERO_LEN = 1 << 2,
-  ASAN_CHECK_START_INSTRUMENTED = 1 << 3,
-  ASAN_CHECK_END_INSTRUMENTED = 1 << 4,
-  ASAN_CHECK_LAST
+  ASAN_CHECK_LAST = 1 << 3
 };
 
 /* Hashtable support for memory references used by gimple
@@ -352,10 +350,7 @@ struct asan_mem_ref_hasher
 inline hashval_t
 asan_mem_ref_hasher::hash (const asan_mem_ref *mem_ref)
 {
-  inchash::hash hstate;
-  inchash::add_expr (mem_ref->start, hstate);
-  hstate.add_wide_int (mem_ref->access_size);
-  return hstate.end ();
+  return iterative_hash_expr (mem_ref->start, 0);
 }
 
 /* Compare two memory references.  We accept the length of either
@@ -365,8 +360,7 @@ inline bool
 asan_mem_ref_hasher::equal (const asan_mem_ref *m1,
 			const asan_mem_ref *m2)
 {
-  return (m1->access_size == m2->access_size
-	  && operand_equal_p (m1->start, m2->start, 0));
+  return operand_equal_p (m1->start, m2->start, 0);
 }
 
 static hash_table *asan_mem_ref_ht;
@@ -417,7 +411,8 @@ has_mem_ref_been_instrumented (tree ref, HOST_WIDE_INT access_size)
   asan_mem_ref r;
   asan_mem_ref_init (&r, ref, access_size);
 
-  return (get_mem_ref_hash_table ()->find (&r) != NULL);
+  asan_mem_ref *saved_ref = get_mem_ref_hash_table ()->find (&r);
+  return saved_ref && saved_ref->access_size >= access_

Re: [PATCH] PR58867 ASan and UBSan tests not run for installed testing.

2014-10-24 Thread Maxim Ostapenko


On 10/24/2014 02:43 PM, Eric Botcazou wrote:

some time ago, Andrew wrote a patch that fixes PR58867
(http://patchwork.ozlabs.org/patch/286866/), but for some reasons it
wasn't committed to trunk.

This is resurrected Andrew's patch, extended to support Tsan testsuite.

This patch broke --disable-libsanitizer though, i.e. you now get gazillions of
sanitizer failures in the C and C++ testsuites.


Hi,

do you have any other (system) version of GCC, configured without 
--disable-libsanitizer? If so, perhaps your GCC links with system 
asan_preinit.o and links dummy int main () { return 0; } in 
check_effective_target_fsanitize_address successfully, but fails to find 
libasan.so in execution tests because LD_LIBRARY_PATH does not contain 
any path to libasan.so.2.


If so, I see two ways to fix this:

1) Add path to system libs in LD_LIBRARY_PATH explicitly.

2) Make check_effective_target_fsanitize_address not only link dummy 
executable, but also run it and verify that exit code equals zero.


-Maxim


  1   2   3   >