From e60e09a0e0e8c1b17fc35cf25b739666a96010b9 Mon Sep 17 00:00:00 2001
From: Jakub Jelinek <jakub@redhat.com>
Date: Wed, 30 Jan 2013 19:05:53 +0100
Subject: [PATCH] re PR sanitizer/55374 ([asan] -static-libasan
 -static-libstdc++ doesn't work)

	PR sanitizer/55374
	* gcc.c (LIBASAN_SPEC): Define just to ADD_STATIC_LIBASAN_LIBS if
	LIBASAN_EARLY_SPEC is defined.
	(LIBASAN_EARLY_SPEC): Define to empty string if not already defined.
	(LINK_COMMAND_SPEC): Add LIBASAN_EARLY_SPEC for -fsanitize=address,
	before %o.
	* config/gnu-user.h (LIBASAN_EARLY_SPEC): Define.

	* g++.dg/asan/large-func-test-1.C: Allow both _Zna[jm] in addition
	to _Znw[jm] in the backtrace.  Allow _Zna[jm] to be the first frame
	printed in backtrace.
	* g++.dg/asan/deep-stack-uaf-1.C: Use malloc instead of operator new
	to avoid errors about mismatched allocation vs. deallocation.

From-SVN: r195585
---
 gcc/ChangeLog                                 |  8 ++++++++
 gcc/config/gnu-user.h                         |  9 +++++++++
 gcc/gcc.c                                     | 11 +++++++++--
 gcc/testsuite/ChangeLog                       |  7 +++++++
 gcc/testsuite/g++.dg/asan/deep-stack-uaf-1.C  |  2 +-
 gcc/testsuite/g++.dg/asan/large-func-test-1.C |  4 ++--
 6 files changed, 36 insertions(+), 5 deletions(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index dd0b294a469a..c93f31df6d35 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,13 @@
 2013-01-30  Jakub Jelinek  <jakub@redhat.com>
 
+	PR sanitizer/55374
+	* gcc.c (LIBASAN_SPEC): Define just to ADD_STATIC_LIBASAN_LIBS if
+	LIBASAN_EARLY_SPEC is defined.
+	(LIBASAN_EARLY_SPEC): Define to empty string if not already defined.
+	(LINK_COMMAND_SPEC): Add LIBASAN_EARLY_SPEC for -fsanitize=address,
+	before %o.
+	* config/gnu-user.h (LIBASAN_EARLY_SPEC): Define.
+
 	PR c++/55742
 	* config/i386/i386.c (ix86_valid_target_attribute_inner_p): Diagnose
 	invalid args instead of ICEing on it.
diff --git a/gcc/config/gnu-user.h b/gcc/config/gnu-user.h
index 43f0ee001e4a..6e3bbb48dff5 100644
--- a/gcc/config/gnu-user.h
+++ b/gcc/config/gnu-user.h
@@ -98,6 +98,15 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #define TARGET_C99_FUNCTIONS 1
 #define TARGET_HAS_SINCOS 1
 
+/* Link -lasan early on the command line.  For -static-libasan, don't link
+   it for -shared link, the executable should be compiled with -static-libasan
+   in that case, and for executable link link with --{,no-}whole-archive around
+   it to force everything into the executable.  */
+#undef LIBASAN_EARLY_SPEC
+#define LIBASAN_EARLY_SPEC "%{static-libasan:%{!shared:" \
+  LD_STATIC_OPTION " --whole-archive -lasan --no-whole-archive " \
+  LD_DYNAMIC_OPTION "}}%{!static-libasan:-lasan}"
+
 /* Additional libraries needed by -static-libasan.  */
 #undef STATIC_LIBASAN_LIBS
 #define STATIC_LIBASAN_LIBS "-ldl -lpthread"
diff --git a/gcc/gcc.c b/gcc/gcc.c
index ff0f5845224d..29735be1b9b2 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -548,7 +548,9 @@ proper position among the other output files.  */
 #else
 #define ADD_STATIC_LIBASAN_LIBS
 #endif
-#ifdef HAVE_LD_STATIC_DYNAMIC
+#ifdef LIBASAN_EARLY_SPEC
+#define LIBASAN_SPEC ADD_STATIC_LIBASAN_LIBS
+#elif defined(HAVE_LD_STATIC_DYNAMIC)
 #define LIBASAN_SPEC "%{static-libasan:" LD_STATIC_OPTION \
 		     "} -lasan %{static-libasan:" LD_DYNAMIC_OPTION "}" \
 		     ADD_STATIC_LIBASAN_LIBS
@@ -557,6 +559,10 @@ proper position among the other output files.  */
 #endif
 #endif
 
+#ifndef LIBASAN_EARLY_SPEC
+#define LIBASAN_EARLY_SPEC ""
+#endif
+
 #ifndef LIBTSAN_SPEC
 #ifdef HAVE_LD_STATIC_DYNAMIC
 #define LIBTSAN_SPEC "%{static-libtsan:" LD_STATIC_OPTION \
@@ -705,7 +711,8 @@ proper position among the other output files.  */
    "%{fuse-ld=*:-fuse-ld=%*}\
     %X %{o*} %{e*} %{N} %{n} %{r}\
     %{s} %{t} %{u*} %{z} %{Z} %{!nostdlib:%{!nostartfiles:%S}}\
-    %{static:} %{L*} %(mfwrap) %(link_libgcc) %o\
+    %{static:} %{L*} %(mfwrap) %(link_libgcc) \
+    %{fsanitize=address:" LIBASAN_EARLY_SPEC "} %o\
     %{fopenmp|ftree-parallelize-loops=*:%:include(libgomp.spec)%(link_gomp)}\
     %{fgnu-tm:%:include(libitm.spec)%(link_itm)}\
     %(mflib) " STACK_SPLIT_SPEC "\
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 215ab43d2526..edd3d1489688 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,12 @@
 2013-01-30  Jakub Jelinek  <jakub@redhat.com>
 
+	PR sanitizer/55374
+	* g++.dg/asan/large-func-test-1.C: Allow both _Zna[jm] in addition
+	to _Znw[jm] in the backtrace.  Allow _Zna[jm] to be the first frame
+	printed in backtrace.
+	* g++.dg/asan/deep-stack-uaf-1.C: Use malloc instead of operator new
+	to avoid errors about mismatched allocation vs. deallocation.
+
 	PR c++/55742
 	* g++.dg/mv1.C: Moved to...
 	* g++.dg/ext/mv1.C: ... here.  Adjust test.
diff --git a/gcc/testsuite/g++.dg/asan/deep-stack-uaf-1.C b/gcc/testsuite/g++.dg/asan/deep-stack-uaf-1.C
index 76779959ad77..6ffec4c4c6de 100644
--- a/gcc/testsuite/g++.dg/asan/deep-stack-uaf-1.C
+++ b/gcc/testsuite/g++.dg/asan/deep-stack-uaf-1.C
@@ -27,7 +27,7 @@ struct DeepFree<0> {
 };
 
 int main() {
-  char *x = new char[10];
+  char *x = (char*)malloc(10);
   // deep_free(x);
   DeepFree<200>::free(x);
   return x[5];
diff --git a/gcc/testsuite/g++.dg/asan/large-func-test-1.C b/gcc/testsuite/g++.dg/asan/large-func-test-1.C
index 32981fa4b734..32808e7a8bba 100644
--- a/gcc/testsuite/g++.dg/asan/large-func-test-1.C
+++ b/gcc/testsuite/g++.dg/asan/large-func-test-1.C
@@ -41,5 +41,5 @@ int main() {
 // { dg-output "    #0 0x\[0-9a-f\]+ (in \[^\n\r]*LargeFunction\[^\n\r]*(large-func-test-1.C:18|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" }
 // { dg-output "0x\[0-9a-f\]+ is located 44 bytes to the right of 400-byte region.*(\n|\r\n|\r)" }
 // { dg-output "allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" }
-// { dg-output "    #0 0x\[0-9a-f\]+ (in _*(interceptor_|)malloc|\[(\])\[^\n\r]*(\n|\r\n|\r)" }
-// { dg-output "    #1 0x\[0-9a-f\]+ (in (operator new|_*_Znw\[mj\])|\[(\])\[^\n\r]*(\n|\r\n|\r)" }
+// { dg-output "    #0( 0x\[0-9a-f\]+ (in _*(interceptor_|)malloc|\[(\])\[^\n\r]*(\n|\r\n|\r)" }
+// { dg-output "    #1|) 0x\[0-9a-f\]+ (in (operator new|_*_Zn\[aw\]\[mj\])|\[(\])\[^\n\r]*(\n|\r\n|\r)" }
-- 
GitLab