From 7d61373544eb18698bd9015f73940048aeb4324e Mon Sep 17 00:00:00 2001
From: Jakub Jelinek <jakub@redhat.com>
Date: Fri, 22 Feb 2013 17:07:36 +0100
Subject: [PATCH] re PR sanitizer/56393 (SIGSEGV when -fsanitize=address and
 dynamic lib with global objects)

	PR sanitizer/56393
	* config/gnu-user.h (LIBASAN_EARLY_SPEC): Link in libasan_preinit.o
	if not linking a shared library.

	* lib/asan-dg.exp (asan_link_flags): Add
	-B${gccpath}/libsanitizer/asan/ to flags.

	* asan/Makefile.am (nodist_toolexeclib_HEADERS): Set to
	libasan_preinit.o.
	(libasan_preinit.o): Depend on asan_preinit.o.
	* asan/Makefile.in: Regenerated.
	* asan/asan_preinit.cc: New file, synced from upstream.
	* asan/asan_rtl.cc: Remove preinit stuff, synced from upstream.

From-SVN: r196222
---
 gcc/ChangeLog                     |  6 ++++
 gcc/config/gnu-user.h             |  6 ++--
 gcc/testsuite/ChangeLog           |  6 ++++
 gcc/testsuite/lib/asan-dg.exp     |  1 +
 libsanitizer/ChangeLog            | 10 ++++++
 libsanitizer/asan/Makefile.am     |  4 +++
 libsanitizer/asan/Makefile.in     | 55 ++++++++++++++++++++++++-------
 libsanitizer/asan/asan_preinit.cc | 27 +++++++++++++++
 libsanitizer/asan/asan_rtl.cc     | 14 --------
 9 files changed, 101 insertions(+), 28 deletions(-)
 create mode 100644 libsanitizer/asan/asan_preinit.cc

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e39c57fcf2dc..e7cd74931d91 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2013-02-22  Jakub Jelinek  <jakub@redhat.com>
+
+	PR sanitizer/56393
+	* config/gnu-user.h (LIBASAN_EARLY_SPEC): Link in libasan_preinit.o
+	if not linking a shared library.
+
 2013-02-22  Seth LaForge  <sethml@google.com>
 
 	* config.gcc (arm*-*-eabi*): Treat arm*eb as big-endian.
diff --git a/gcc/config/gnu-user.h b/gcc/config/gnu-user.h
index ba627e0ab0dc..6c26163b2238 100644
--- a/gcc/config/gnu-user.h
+++ b/gcc/config/gnu-user.h
@@ -104,11 +104,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
    it to force everything into the executable.  And similarly for -ltsan.  */
 #if defined(HAVE_LD_STATIC_DYNAMIC)
 #undef LIBASAN_EARLY_SPEC
-#define LIBASAN_EARLY_SPEC "%{static-libasan:%{!shared:" \
+#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}"
 #undef LIBTSAN_EARLY_SPEC
-#define LIBTSAN_EARLY_SPEC "%{static-libtsan:%{!shared:" \
+#define LIBTSAN_EARLY_SPEC "%{!shared:libasan_preinit%O%s} " \
+  "%{static-libtsan:%{!shared:" \
   LD_STATIC_OPTION " --whole-archive -ltsan --no-whole-archive " \
   LD_DYNAMIC_OPTION "}}%{!static-libtsan:-ltsan}"
 #endif
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 7df8623d2889..351cb17d8ee2 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2013-02-22  Jakub Jelinek  <jakub@redhat.com>
+
+	PR sanitizer/56393
+	* lib/asan-dg.exp (asan_link_flags): Add
+	-B${gccpath}/libsanitizer/asan/ to flags.
+
 2013-02-21  Jakub Jelinek  <jakub@redhat.com>
 
 	PR middle-end/56420
diff --git a/gcc/testsuite/lib/asan-dg.exp b/gcc/testsuite/lib/asan-dg.exp
index 0bc9b245d79c..e0bf2da2e783 100644
--- a/gcc/testsuite/lib/asan-dg.exp
+++ b/gcc/testsuite/lib/asan-dg.exp
@@ -41,6 +41,7 @@ proc asan_link_flags { paths } {
     if { $gccpath != "" } {
       if { [file exists "${gccpath}/libsanitizer/asan/.libs/libasan.a"]
 	   || [file exists "${gccpath}/libsanitizer/asan/.libs/libasan.${shlib_ext}"] } {
+	  append flags " -B${gccpath}/libsanitizer/asan/ "
 	  append flags " -L${gccpath}/libsanitizer/asan/.libs "
 	  append ld_library_path ":${gccpath}/libsanitizer/asan/.libs"
       }
diff --git a/libsanitizer/ChangeLog b/libsanitizer/ChangeLog
index 7f8f6ad77584..608ffab0851f 100644
--- a/libsanitizer/ChangeLog
+++ b/libsanitizer/ChangeLog
@@ -1,3 +1,13 @@
+2013-02-22  Jakub Jelinek  <jakub@redhat.com>
+
+	PR sanitizer/56393
+	* asan/Makefile.am (nodist_toolexeclib_HEADERS): Set to
+	libasan_preinit.o.
+	(libasan_preinit.o): Depend on asan_preinit.o.
+	* asan/Makefile.in: Regenerated.
+	* asan/asan_preinit.cc: New file, synced from upstream.
+	* asan/asan_rtl.cc: Remove preinit stuff, synced from upstream.
+
 2013-02-21  Jack Howarth <howarth@bromo.med.uc.edu>
 
 	* asan/Makefile.am (libasan_la_SOURCES): Remove deprecated
diff --git a/libsanitizer/asan/Makefile.am b/libsanitizer/asan/Makefile.am
index b3ca3df31e13..f7847db36471 100644
--- a/libsanitizer/asan/Makefile.am
+++ b/libsanitizer/asan/Makefile.am
@@ -12,6 +12,7 @@ AM_CXXFLAGS += $(LIBSTDCXX_RAW_CXX_CXXFLAGS)
 ACLOCAL_AMFLAGS = -I $(top_srcdir) -I $(top_srcdir)/config
 
 toolexeclib_LTLIBRARIES = libasan.la
+nodist_toolexeclib_HEADERS = libasan_preinit.o
 
 asan_files = \
 	asan_allocator.cc \
@@ -45,6 +46,9 @@ libasan_la_LIBADD += $(LIBSTDCXX_RAW_CXX_LDFLAGS)
 
 libasan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` -lpthread -ldl
 
+libasan_preinit.o: asan_preinit.o
+	cp $< $@
+
 # Work around what appears to be a GNU make bug handling MAKEFLAGS
 # values defined in terms of make variables, as is the case for CC and
 # friends when we are called from the top level Makefile.
diff --git a/libsanitizer/asan/Makefile.in b/libsanitizer/asan/Makefile.in
index d5688be6ba26..d54f3a7be366 100644
--- a/libsanitizer/asan/Makefile.in
+++ b/libsanitizer/asan/Makefile.in
@@ -15,6 +15,7 @@
 
 @SET_MAKE@
 
+
 VPATH = @srcdir@
 pkgdatadir = $(datadir)/@PACKAGE@
 pkgincludedir = $(includedir)/@PACKAGE@
@@ -75,7 +76,8 @@ am__nobase_list = $(am__nobase_strip_setup); \
 am__base_list = \
   sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
   sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
-am__installdirs = "$(DESTDIR)$(toolexeclibdir)"
+am__installdirs = "$(DESTDIR)$(toolexeclibdir)" \
+	"$(DESTDIR)$(toolexeclibdir)"
 LTLIBRARIES = $(toolexeclib_LTLIBRARIES)
 am__DEPENDENCIES_1 =
 @USING_MAC_INTERPOSE_FALSE@libasan_la_DEPENDENCIES = $(top_builddir)/sanitizer_common/libsanitizer_common.la \
@@ -110,6 +112,7 @@ CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
 	$(LDFLAGS) -o $@
 SOURCES = $(libasan_la_SOURCES)
 DIST_SOURCES = $(libasan_la_SOURCES)
+HEADERS = $(nodist_toolexeclib_HEADERS)
 ETAGS = etags
 CTAGS = ctags
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
@@ -257,6 +260,7 @@ AM_CXXFLAGS = -Wall -W -Wno-unused-parameter -Wwrite-strings -pedantic \
 	-Wno-variadic-macros $(LIBSTDCXX_RAW_CXX_CXXFLAGS)
 ACLOCAL_AMFLAGS = -I $(top_srcdir) -I $(top_srcdir)/config
 toolexeclib_LTLIBRARIES = libasan.la
+nodist_toolexeclib_HEADERS = libasan_preinit.o
 asan_files = \
 	asan_allocator.cc \
 	asan_allocator2.cc \
@@ -447,6 +451,26 @@ mostlyclean-libtool:
 
 clean-libtool:
 	-rm -rf .libs _libs
+install-nodist_toolexeclibHEADERS: $(nodist_toolexeclib_HEADERS)
+	@$(NORMAL_INSTALL)
+	test -z "$(toolexeclibdir)" || $(MKDIR_P) "$(DESTDIR)$(toolexeclibdir)"
+	@list='$(nodist_toolexeclib_HEADERS)'; test -n "$(toolexeclibdir)" || list=; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(toolexeclibdir)'"; \
+	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(toolexeclibdir)" || exit $$?; \
+	done
+
+uninstall-nodist_toolexeclibHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(nodist_toolexeclib_HEADERS)'; test -n "$(toolexeclibdir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	test -n "$$files" || exit 0; \
+	echo " ( cd '$(DESTDIR)$(toolexeclibdir)' && rm -f" $$files ")"; \
+	cd "$(DESTDIR)$(toolexeclibdir)" && rm -f $$files
 
 ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
 	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
@@ -532,9 +556,9 @@ distdir: $(DISTFILES)
 	done
 check-am: all-am
 check: check-am
-all-am: Makefile $(LTLIBRARIES)
+all-am: Makefile $(LTLIBRARIES) $(HEADERS)
 installdirs:
-	for dir in "$(DESTDIR)$(toolexeclibdir)"; do \
+	for dir in "$(DESTDIR)$(toolexeclibdir)" "$(DESTDIR)$(toolexeclibdir)"; do \
 	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
 	done
 install: install-am
@@ -591,7 +615,8 @@ install-dvi: install-dvi-am
 
 install-dvi-am:
 
-install-exec-am: install-toolexeclibLTLIBRARIES
+install-exec-am: install-nodist_toolexeclibHEADERS \
+	install-toolexeclibLTLIBRARIES
 
 install-html: install-html-am
 
@@ -631,7 +656,8 @@ ps: ps-am
 
 ps-am:
 
-uninstall-am: uninstall-toolexeclibLTLIBRARIES
+uninstall-am: uninstall-nodist_toolexeclibHEADERS \
+	uninstall-toolexeclibLTLIBRARIES
 
 .MAKE: install-am install-strip
 
@@ -642,13 +668,18 @@ uninstall-am: uninstall-toolexeclibLTLIBRARIES
 	install install-am install-data install-data-am install-dvi \
 	install-dvi-am install-exec install-exec-am install-html \
 	install-html-am install-info install-info-am install-man \
-	install-pdf install-pdf-am install-ps install-ps-am \
-	install-strip install-toolexeclibLTLIBRARIES installcheck \
-	installcheck-am installdirs maintainer-clean \
-	maintainer-clean-generic mostlyclean mostlyclean-compile \
-	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
-	tags uninstall uninstall-am uninstall-toolexeclibLTLIBRARIES
-
+	install-nodist_toolexeclibHEADERS install-pdf install-pdf-am \
+	install-ps install-ps-am install-strip \
+	install-toolexeclibLTLIBRARIES installcheck installcheck-am \
+	installdirs maintainer-clean maintainer-clean-generic \
+	mostlyclean mostlyclean-compile mostlyclean-generic \
+	mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \
+	uninstall-am uninstall-nodist_toolexeclibHEADERS \
+	uninstall-toolexeclibLTLIBRARIES
+
+
+libasan_preinit.o: asan_preinit.o
+	cp $< $@
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/libsanitizer/asan/asan_preinit.cc b/libsanitizer/asan/asan_preinit.cc
new file mode 100644
index 000000000000..40309fa389de
--- /dev/null
+++ b/libsanitizer/asan/asan_preinit.cc
@@ -0,0 +1,27 @@
+//===-- asan_preinit.cc ---------------------------------------------------===//
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of AddressSanitizer, an address sanity checker.
+//
+// Call __asan_init at the very early stage of process startup.
+// On Linux we use .preinit_array section (unless PIC macro is defined).
+//===----------------------------------------------------------------------===//
+#include "asan_internal.h"
+
+#if ASAN_USE_PREINIT_ARRAY && !defined(PIC)
+  // On Linux, we force __asan_init to be called before anyone else
+  // by placing it into .preinit_array section.
+  // FIXME: do we have anything like this on Mac?
+  __attribute__((section(".preinit_array"), used))
+  void (*__asan_preinit)(void) =__asan_init;
+#elif defined(_WIN32) && defined(_DLL)
+  // On Windows, when using dynamic CRT (/MD), we can put a pointer
+  // to __asan_init into the global list of C initializers.
+  // See crt0dat.c in the CRT sources for the details.
+  #pragma section(".CRT$XIB", long, read)  // NOLINT
+  __declspec(allocate(".CRT$XIB")) void (*__asan_preinit)() = __asan_init;
+#endif
diff --git a/libsanitizer/asan/asan_rtl.cc b/libsanitizer/asan/asan_rtl.cc
index 4b0afd2731a3..e551b6fbc26d 100644
--- a/libsanitizer/asan/asan_rtl.cc
+++ b/libsanitizer/asan/asan_rtl.cc
@@ -519,17 +519,3 @@ void __asan_init() {
     Report("AddressSanitizer Init done\n");
   }
 }
-
-#if ASAN_USE_PREINIT_ARRAY && !defined (PIC)
-  // On Linux, we force __asan_init to be called before anyone else
-  // by placing it into .preinit_array section.
-  // FIXME: do we have anything like this on Mac?
-  __attribute__((section(".preinit_array"), used))
-  void (*__asan_preinit)(void) =__asan_init;
-#elif defined(_WIN32) && defined(_DLL)
-  // On Windows, when using dynamic CRT (/MD), we can put a pointer
-  // to __asan_init into the global list of C initializers.
-  // See crt0dat.c in the CRT sources for the details.
-  #pragma section(".CRT$XIB", long, read)  // NOLINT
-  __declspec(allocate(".CRT$XIB")) void (*__asan_preinit)() = __asan_init;
-#endif
-- 
GitLab