diff mbox

Support -fsanitize=leak

Message ID 20131115194138.GQ892@tucnak.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek Nov. 15, 2013, 7:41 p.m. UTC
Hi!

This patch adds support for -fsanitize=leak and -static-liblsan options.
If combined with -fsanitize=address, it does nothing, otherwise it links
in liblsan, a new shared+static library (on x86_64-linux only so far,
the code isn't 32-bit ready apparently).

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2013-11-14  Jakub Jelinek  <jakub@redhat.com>

	PR sanitizer/59061
	* common.opt (static-liblsan): Add.
	* config/gnu-user.h (STATIC_LIBLSAN_LIBS, STATIC_LIBUBSAN_LIBS):
	Define.
	* flag-types.h (enum sanitize_code): Add SANITIZE_LEAK.  Renumber
	SANITIZE_SHIFT, SANITIZE_DIVIDE, SANITIZE_UNREACHABLE, SANITIZE_VLA.
	* opts.c (common_handle_option): Handle -fsanitize=leak.
	* gcc.c (ADD_STATIC_LIBLSAN_LIBS, LIBLSAN_SPEC): Define.
	(LIBUBSAN_SPEC): Don't test LIBUBSAN_EARLY_SPEC.
	(LIBUBSAN_EARLY_SPEC): Remove.
	(SANITIZER_EARLY_SPEC): Don't do anything for libubsan.
	(SANITIZER_SPEC): Add -fsanitize=leak handling.
	(sanitize_spec_function): Handle %sanitize(leak).

	* configure.tgt: Set LSAN_SUPPORTED=yes for x86_64-linux.
	* configure.ac (LSAN_SUPPORTED): New AM_CONDITIONAL.
	* lsan/Makefile.am (toolexeclib_LTLIBRARIES, lsan_files,
	liblsan_la_SOURCES, liblsan_la_LIBADD, liblsan_la_LDFLAGS): Add.
	* lsan/Makefile.in: Regenerated.


	Jakub

Comments

Ian Lance Taylor Nov. 15, 2013, 8:34 p.m. UTC | #1
On Fri, Nov 15, 2013 at 11:41 AM, Jakub Jelinek <jakub@redhat.com> wrote:
>
> This patch adds support for -fsanitize=leak and -static-liblsan options.
> If combined with -fsanitize=address, it does nothing, otherwise it links
> in liblsan, a new shared+static library (on x86_64-linux only so far,
> the code isn't 32-bit ready apparently).
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

Documentation?

Ian
Marek Polacek Nov. 18, 2013, 12:15 p.m. UTC | #2
On Fri, Nov 15, 2013 at 08:41:38PM +0100, Jakub Jelinek wrote:
> Hi!
> 
> This patch adds support for -fsanitize=leak and -static-liblsan options.
> If combined with -fsanitize=address, it does nothing, otherwise it links
> in liblsan, a new shared+static library (on x86_64-linux only so far,
> the code isn't 32-bit ready apparently).
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
> 
> 2013-11-14  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR sanitizer/59061
> 	* common.opt (static-liblsan): Add.
> 	* config/gnu-user.h (STATIC_LIBLSAN_LIBS, STATIC_LIBUBSAN_LIBS):
> 	Define.
> 	* flag-types.h (enum sanitize_code): Add SANITIZE_LEAK.  Renumber
> 	SANITIZE_SHIFT, SANITIZE_DIVIDE, SANITIZE_UNREACHABLE, SANITIZE_VLA.
> 	* opts.c (common_handle_option): Handle -fsanitize=leak.
> 	* gcc.c (ADD_STATIC_LIBLSAN_LIBS, LIBLSAN_SPEC): Define.
> 	(LIBUBSAN_SPEC): Don't test LIBUBSAN_EARLY_SPEC.
> 	(LIBUBSAN_EARLY_SPEC): Remove.
> 	(SANITIZER_EARLY_SPEC): Don't do anything for libubsan.
> 	(SANITIZER_SPEC): Add -fsanitize=leak handling.
> 	(sanitize_spec_function): Handle %sanitize(leak).
> 
> 	* configure.tgt: Set LSAN_SUPPORTED=yes for x86_64-linux.
> 	* configure.ac (LSAN_SUPPORTED): New AM_CONDITIONAL.
> 	* lsan/Makefile.am (toolexeclib_LTLIBRARIES, lsan_files,
> 	liblsan_la_SOURCES, liblsan_la_LIBADD, liblsan_la_LDFLAGS): Add.
> 	* lsan/Makefile.in: Regenerated.

Looks good to me.  Moreover, it fixes the bootstrap-ubsan failure when
building fixincl - I guess the gnu-user.h hunk was missing.  Thanks.

	Marek
Marek Polacek Nov. 18, 2013, 2:01 p.m. UTC | #3
On Mon, Nov 18, 2013 at 01:15:02PM +0100, Marek Polacek wrote:
> Moreover, it fixes the bootstrap-ubsan failure when
> building fixincl - I guess the gnu-user.h hunk was missing.  Thanks.

Sorry, turned out this is bogus.  It really will need some
configure/Makefile fix.

	Marek
Dodji Seketeli Nov. 22, 2013, 8:47 p.m. UTC | #4
Jakub Jelinek <jakub@redhat.com> writes:

> This patch adds support for -fsanitize=leak and -static-liblsan options.
> If combined with -fsanitize=address, it does nothing,

From this hunk:

    @@ -8123,7 +8133,10 @@ sanitize_spec_function (int argc, const
	 return (flag_sanitize & SANITIZE_THREAD) ? "" : NULL;
       if (strcmp (argv[0], "undefined") == 0)
	 return (flag_sanitize & SANITIZE_UNDEFINED) ? "" : NULL;
    -
    +  if (strcmp (argv[0], "leak") == 0)
    +    return ((flag_sanitize
    +	     & (SANITIZE_ADDRESS | SANITIZE_LEAK | SANITIZE_THREAD))
    +	    == SANITIZE_LEAK) ? "" : NULL;
       return NULL;
     }

I'd say if combined with -fsanitize={address,thread} it does nothing,
right?

I'd say this needs some tests as well, but I guess they are coming a
bit later in the cycle?

[...]

> On Fri, Nov 15, 2013 at 12:34:14PM -0800, Ian Lance Taylor wrote:

>> Documentation?
>
> Here it is, as incremental patch:
>
> 2013-11-18  Jakub Jelinek  <jakub@redhat.com>
>
> 	* doc/invoke.texi (-static-liblsan, -fsanitize=leak): Document.

[...]


> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

Yes, this is OK with the incremental patch for the documentation.

Thanks.
Jakub Jelinek Nov. 22, 2013, 8:53 p.m. UTC | #5
On Fri, Nov 22, 2013 at 09:47:13PM +0100, Dodji Seketeli wrote:
> > This patch adds support for -fsanitize=leak and -static-liblsan options.
> > If combined with -fsanitize=address, it does nothing,
> 
> >From this hunk:
> 
>     @@ -8123,7 +8133,10 @@ sanitize_spec_function (int argc, const
> 	 return (flag_sanitize & SANITIZE_THREAD) ? "" : NULL;
>        if (strcmp (argv[0], "undefined") == 0)
> 	 return (flag_sanitize & SANITIZE_UNDEFINED) ? "" : NULL;
>     -
>     +  if (strcmp (argv[0], "leak") == 0)
>     +    return ((flag_sanitize
>     +	     & (SANITIZE_ADDRESS | SANITIZE_LEAK | SANITIZE_THREAD))
>     +	    == SANITIZE_LEAK) ? "" : NULL;
>        return NULL;
>      }
> 
> I'd say if combined with -fsanitize={address,thread} it does nothing,
> right?

Yes.  The libasan library can do the leak detection too, though unlike
liblsan doesn't do it by default right now, needs to be enabled through
environment.  Dunno about tsan, but all the 3 libraries certainly are
incompatible with each other.

Perhaps __asan_init_v3 could be changed to __asan_init_v4 and pass
some flags to the library, where one of the bits would be whether
to enable leak detector by default or not?  Just a thought...

> I'd say this needs some tests as well, but I guess they are coming a
> bit later in the cycle?

Yeah.

> > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
> 
> Yes, this is OK with the incremental patch for the documentation.

Thanks.

	Jakub
diff mbox

Patch

--- gcc/common.opt.jj	2013-11-12 11:31:26.000000000 +0100
+++ gcc/common.opt	2013-11-14 17:51:21.909731442 +0100
@@ -2650,6 +2650,9 @@  Driver
 static-libtsan
 Driver
 
+static-liblsan
+Driver
+
 static-libubsan
 Driver
 
--- gcc/config/gnu-user.h.jj	2013-08-23 09:28:04.000000000 +0200
+++ gcc/config/gnu-user.h	2013-11-14 17:40:30.405051058 +0100
@@ -134,3 +134,11 @@  see the files COPYING3 and COPYING.RUNTI
 /* Additional libraries needed by -static-libtsan.  */
 #undef STATIC_LIBTSAN_LIBS
 #define STATIC_LIBTSAN_LIBS "-ldl -lpthread"
+
+/* Additional libraries needed by -static-liblsan.  */
+#undef STATIC_LIBLSAN_LIBS
+#define STATIC_LIBLSAN_LIBS "-ldl -lpthread"
+
+/* Additional libraries needed by -static-libubsan.  */
+#undef STATIC_LIBUBSAN_LIBS
+#define STATIC_LIBUBSAN_LIBS "-ldl -lpthread"
--- gcc/flag-types.h.jj	2013-11-12 11:31:25.000000000 +0100
+++ gcc/flag-types.h	2013-11-14 17:41:37.524713187 +0100
@@ -206,11 +206,13 @@  enum sanitize_code {
   SANITIZE_ADDRESS = 1 << 0,
   /* ThreadSanitizer.  */
   SANITIZE_THREAD = 1 << 1,
+  /* LeakSanitizer.  */
+  SANITIZE_LEAK = 1 << 2,
   /* UndefinedBehaviorSanitizer.  */
-  SANITIZE_SHIFT = 1 << 2,
-  SANITIZE_DIVIDE = 1 << 3,
-  SANITIZE_UNREACHABLE = 1 << 4,
-  SANITIZE_VLA = 1 << 5,
+  SANITIZE_SHIFT = 1 << 3,
+  SANITIZE_DIVIDE = 1 << 4,
+  SANITIZE_UNREACHABLE = 1 << 5,
+  SANITIZE_VLA = 1 << 6,
   SANITIZE_UNDEFINED = SANITIZE_SHIFT | SANITIZE_DIVIDE | SANITIZE_UNREACHABLE
 		       | SANITIZE_VLA
 };
--- gcc/opts.c.jj	2013-11-12 11:31:23.000000000 +0100
+++ gcc/opts.c	2013-11-14 17:43:08.719248472 +0100
@@ -1439,6 +1439,7 @@  common_handle_option (struct gcc_options
 	    {
 	      { "address", SANITIZE_ADDRESS, sizeof "address" - 1 },
 	      { "thread", SANITIZE_THREAD, sizeof "thread" - 1 },
+	      { "leak", SANITIZE_LEAK, sizeof "leak" - 1 },
 	      { "shift", SANITIZE_SHIFT, sizeof "shift" - 1 },
 	      { "integer-divide-by-zero", SANITIZE_DIVIDE,
 		sizeof "integer-divide-by-zero" - 1 },
--- gcc/gcc.c.jj	2013-11-12 11:31:12.000000000 +0100
+++ gcc/gcc.c	2013-11-14 17:51:35.271674083 +0100
@@ -578,6 +578,22 @@  proper position among the other output f
 #define LIBTSAN_EARLY_SPEC ""
 #endif
 
+#ifndef LIBLSAN_SPEC
+#ifdef STATIC_LIBLSAN_LIBS
+#define ADD_STATIC_LIBLSAN_LIBS \
+  " %{static-liblsan:" STATIC_LIBLSAN_LIBS "}"
+#else
+#define ADD_STATIC_LIBLSAN_LIBS
+#endif
+#ifdef HAVE_LD_STATIC_DYNAMIC
+#define LIBLSAN_SPEC "%{!shared:%{static-liblsan:" LD_STATIC_OPTION \
+		     "} -llsan %{static-liblsan:" LD_DYNAMIC_OPTION "}" \
+		     ADD_STATIC_LIBLSAN_LIBS "}"
+#else
+#define LIBLSAN_SPEC "%{!shared:-llsan" ADD_STATIC_LIBLSAN_LIBS "}"
+#endif
+#endif
+
 #ifndef LIBUBSAN_SPEC
 #ifdef STATIC_LIBUBSAN_LIBS
 #define ADD_STATIC_LIBUBSAN_LIBS \
@@ -585,9 +601,7 @@  proper position among the other output f
 #else
 #define ADD_STATIC_LIBUBSAN_LIBS
 #endif
-#ifdef LIBUBSAN_EARLY_SPEC
-#define LIBUBSAN_SPEC ADD_STATIC_LIBUBSAN_LIBS
-#elif defined(HAVE_LD_STATIC_DYNAMIC)
+#ifdef HAVE_LD_STATIC_DYNAMIC
 #define LIBUBSAN_SPEC "%{static-libubsan:" LD_STATIC_OPTION \
 		     "} -lubsan %{static-libubsan:" LD_DYNAMIC_OPTION "}" \
 		     ADD_STATIC_LIBUBSAN_LIBS
@@ -596,10 +610,6 @@  proper position among the other output f
 #endif
 #endif
 
-#ifndef LIBUBSAN_EARLY_SPEC
-#define LIBUBSAN_EARLY_SPEC ""
-#endif
-
 /* config.h can define LIBGCC_SPEC to override how and when libgcc.a is
    included.  */
 #ifndef LIBGCC_SPEC
@@ -723,8 +733,7 @@  proper position among the other output f
 #ifndef SANITIZER_EARLY_SPEC
 #define SANITIZER_EARLY_SPEC "\
 %{!nostdlib:%{!nodefaultlibs:%{%:sanitize(address):" LIBASAN_EARLY_SPEC "} \
-    %{%:sanitize(thread):" LIBTSAN_EARLY_SPEC "} \
-    %{%:sanitize(undefined):" LIBUBSAN_EARLY_SPEC "}}}"
+    %{%:sanitize(thread):" LIBTSAN_EARLY_SPEC "}}}"
 #endif
 
 /* Linker command line options for -fsanitize= late on the command line.  */
@@ -735,7 +744,8 @@  proper position among the other output f
     %{%:sanitize(thread):%e-fsanitize=address is incompatible with -fsanitize=thread}}\
     %{%:sanitize(thread):" LIBTSAN_SPEC "\
     %{!pie:%{!shared:%e-fsanitize=thread linking must be done with -pie or -shared}}}\
-    %{%:sanitize(undefined):" LIBUBSAN_SPEC "}}}"
+    %{%:sanitize(undefined):" LIBUBSAN_SPEC "}\
+    %{%:sanitize(leak):" LIBLSAN_SPEC "}}}"
 #endif
 
 /*  This is the spec to use, once the code for creating the vtable
@@ -8123,7 +8133,10 @@  sanitize_spec_function (int argc, const
     return (flag_sanitize & SANITIZE_THREAD) ? "" : NULL;
   if (strcmp (argv[0], "undefined") == 0)
     return (flag_sanitize & SANITIZE_UNDEFINED) ? "" : NULL;
-
+  if (strcmp (argv[0], "leak") == 0)
+    return ((flag_sanitize
+	     & (SANITIZE_ADDRESS | SANITIZE_LEAK | SANITIZE_THREAD))
+	    == SANITIZE_LEAK) ? "" : NULL;
   return NULL;
 }
 
--- libsanitizer/lsan/Makefile.am.jj	2013-11-05 10:51:54.834837776 +0100
+++ libsanitizer/lsan/Makefile.am	2013-11-15 17:26:40.089912371 +0100
@@ -9,13 +9,27 @@  AM_CXXFLAGS += $(LIBSTDCXX_RAW_CXX_CXXFL
 ACLOCAL_AMFLAGS = -I m4
 
 noinst_LTLIBRARIES = libsanitizer_lsan.la
+if LSAN_SUPPORTED
+toolexeclib_LTLIBRARIES = liblsan.la
+endif
 
 sanitizer_lsan_files = \
 	lsan_common.cc \
 	lsan_common_linux.cc
 
+lsan_files = \
+	$(sanitizer_lsan_files) \
+	lsan.cc \
+	lsan_allocator.cc \
+	lsan_interceptors.cc \
+	lsan_thread.cc
+
 libsanitizer_lsan_la_SOURCES = $(sanitizer_lsan_files)
 
+liblsan_la_SOURCES = $(lsan_files)
+liblsan_la_LIBADD = $(top_builddir)/sanitizer_common/libsanitizer_common.la $(top_builddir)/interception/libinterception.la $(LIBSTDCXX_RAW_CXX_LDFLAGS)
+liblsan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` -lpthread -ldl
+
 # 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.
--- libsanitizer/configure.tgt.jj	2013-05-09 16:19:36.000000000 +0200
+++ libsanitizer/configure.tgt	2013-11-15 17:25:51.122915290 +0100
@@ -23,6 +23,7 @@  case "${target}" in
   x86_64-*-linux* | i?86-*-linux*)
 	if test x$ac_cv_sizeof_void_p = x8; then
 		TSAN_SUPPORTED=yes
+		LSAN_SUPPORTED=yes
 	fi
 	;;
   powerpc*-*-linux*)
--- libsanitizer/configure.ac.jj	2013-11-05 10:51:54.000000000 +0100
+++ libsanitizer/configure.ac	2013-11-15 17:24:06.854921507 +0100
@@ -78,8 +78,10 @@  fi
 
 # Get target configury.
 unset TSAN_SUPPORTED
+unset LSAN_SUPPORTED
 . ${srcdir}/configure.tgt
 AM_CONDITIONAL(TSAN_SUPPORTED, [test "x$TSAN_SUPPORTED" = "xyes"])
+AM_CONDITIONAL(LSAN_SUPPORTED, [test "x$LSAN_SUPPORTED" = "xyes"])
 
 case "$host" in
   *-*-darwin*) MAC_INTERPOSE=true ; enable_static=no ;;
--- libsanitizer/configure.jj	2013-11-05 10:51:53.000000000 +0100
+++ libsanitizer/configure	2013-11-15 17:27:38.013908917 +0100
@@ -606,6 +606,8 @@  LTLIBOBJS
 LIBOBJS
 USING_MAC_INTERPOSE_FALSE
 USING_MAC_INTERPOSE_TRUE
+LSAN_SUPPORTED_FALSE
+LSAN_SUPPORTED_TRUE
 TSAN_SUPPORTED_FALSE
 TSAN_SUPPORTED_TRUE
 enable_static
@@ -11117,7 +11119,7 @@  else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11120 "configure"
+#line 11122 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11223,7 +11225,7 @@  else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11226 "configure"
+#line 11228 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -14523,6 +14525,7 @@  fi
 
 # Get target configury.
 unset TSAN_SUPPORTED
+unset LSAN_SUPPORTED
 . ${srcdir}/configure.tgt
  if test "x$TSAN_SUPPORTED" = "xyes"; then
   TSAN_SUPPORTED_TRUE=
@@ -14532,6 +14535,14 @@  else
   TSAN_SUPPORTED_FALSE=
 fi
 
+ if test "x$LSAN_SUPPORTED" = "xyes"; then
+  LSAN_SUPPORTED_TRUE=
+  LSAN_SUPPORTED_FALSE='#'
+else
+  LSAN_SUPPORTED_TRUE='#'
+  LSAN_SUPPORTED_FALSE=
+fi
+
 
 case "$host" in
   *-*-darwin*) MAC_INTERPOSE=true ; enable_static=no ;;
@@ -14722,6 +14733,10 @@  if test -z "${TSAN_SUPPORTED_TRUE}" && t
   as_fn_error "conditional \"TSAN_SUPPORTED\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
+if test -z "${LSAN_SUPPORTED_TRUE}" && test -z "${LSAN_SUPPORTED_FALSE}"; then
+  as_fn_error "conditional \"LSAN_SUPPORTED\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
 if test -z "${USING_MAC_INTERPOSE_TRUE}" && test -z "${USING_MAC_INTERPOSE_FALSE}"; then
   as_fn_error "conditional \"USING_MAC_INTERPOSE\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
--- libsanitizer/lsan/Makefile.in.jj	2013-11-05 10:51:54.830837777 +0100
+++ libsanitizer/lsan/Makefile.in	2013-11-15 17:30:18.047899376 +0100
@@ -53,9 +53,44 @@  am__configure_deps = $(am__aclocal_m4_de
 mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs
 CONFIG_CLEAN_FILES =
 CONFIG_CLEAN_VPATH_FILES =
-LTLIBRARIES = $(noinst_LTLIBRARIES)
-libsanitizer_lsan_la_LIBADD =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+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)"
+LTLIBRARIES = $(noinst_LTLIBRARIES) $(toolexeclib_LTLIBRARIES)
+am__DEPENDENCIES_1 =
+liblsan_la_DEPENDENCIES =  \
+	$(top_builddir)/sanitizer_common/libsanitizer_common.la \
+	$(top_builddir)/interception/libinterception.la \
+	$(am__DEPENDENCIES_1)
 am__objects_1 = lsan_common.lo lsan_common_linux.lo
+am__objects_2 = $(am__objects_1) lsan.lo lsan_allocator.lo \
+	lsan_interceptors.lo lsan_thread.lo
+am_liblsan_la_OBJECTS = $(am__objects_2)
+liblsan_la_OBJECTS = $(am_liblsan_la_OBJECTS)
+liblsan_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+	$(CXXFLAGS) $(liblsan_la_LDFLAGS) $(LDFLAGS) -o $@
+@LSAN_SUPPORTED_TRUE@am_liblsan_la_rpath = -rpath $(toolexeclibdir)
+libsanitizer_lsan_la_LIBADD =
 am_libsanitizer_lsan_la_OBJECTS = $(am__objects_1)
 libsanitizer_lsan_la_OBJECTS = $(am_libsanitizer_lsan_la_OBJECTS)
 DEFAULT_INCLUDES = -I.@am__isrc@
@@ -71,7 +106,7 @@  CXXLD = $(CXX)
 CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
 	--mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
 	$(LDFLAGS) -o $@
-SOURCES = $(libsanitizer_lsan_la_SOURCES)
+SOURCES = $(liblsan_la_SOURCES) $(libsanitizer_lsan_la_SOURCES)
 ETAGS = etags
 CTAGS = ctags
 ACLOCAL = @ACLOCAL@
@@ -215,11 +250,22 @@  AM_CXXFLAGS = -Wall -W -Wno-unused-param
 	-Wno-variadic-macros $(LIBSTDCXX_RAW_CXX_CXXFLAGS)
 ACLOCAL_AMFLAGS = -I m4
 noinst_LTLIBRARIES = libsanitizer_lsan.la
+@LSAN_SUPPORTED_TRUE@toolexeclib_LTLIBRARIES = liblsan.la
 sanitizer_lsan_files = \
 	lsan_common.cc \
 	lsan_common_linux.cc
 
+lsan_files = \
+	$(sanitizer_lsan_files) \
+	lsan.cc \
+	lsan_allocator.cc \
+	lsan_interceptors.cc \
+	lsan_thread.cc
+
 libsanitizer_lsan_la_SOURCES = $(sanitizer_lsan_files)
+liblsan_la_SOURCES = $(lsan_files)
+liblsan_la_LIBADD = $(top_builddir)/sanitizer_common/libsanitizer_common.la $(top_builddir)/interception/libinterception.la $(LIBSTDCXX_RAW_CXX_LDFLAGS)
+liblsan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` -lpthread -ldl
 
 # 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
@@ -303,6 +349,39 @@  clean-noinstLTLIBRARIES:
 	  echo "rm -f \"$${dir}/so_locations\""; \
 	  rm -f "$${dir}/so_locations"; \
 	done
+install-toolexeclibLTLIBRARIES: $(toolexeclib_LTLIBRARIES)
+	@$(NORMAL_INSTALL)
+	test -z "$(toolexeclibdir)" || $(MKDIR_P) "$(DESTDIR)$(toolexeclibdir)"
+	@list='$(toolexeclib_LTLIBRARIES)'; test -n "$(toolexeclibdir)" || list=; \
+	list2=; for p in $$list; do \
+	  if test -f $$p; then \
+	    list2="$$list2 $$p"; \
+	  else :; fi; \
+	done; \
+	test -z "$$list2" || { \
+	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(toolexeclibdir)'"; \
+	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(toolexeclibdir)"; \
+	}
+
+uninstall-toolexeclibLTLIBRARIES:
+	@$(NORMAL_UNINSTALL)
+	@list='$(toolexeclib_LTLIBRARIES)'; test -n "$(toolexeclibdir)" || list=; \
+	for p in $$list; do \
+	  $(am__strip_dir) \
+	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(toolexeclibdir)/$$f'"; \
+	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(toolexeclibdir)/$$f"; \
+	done
+
+clean-toolexeclibLTLIBRARIES:
+	-test -z "$(toolexeclib_LTLIBRARIES)" || rm -f $(toolexeclib_LTLIBRARIES)
+	@list='$(toolexeclib_LTLIBRARIES)'; for p in $$list; do \
+	  dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+	  test "$$dir" != "$$p" || dir=.; \
+	  echo "rm -f \"$${dir}/so_locations\""; \
+	  rm -f "$${dir}/so_locations"; \
+	done
+liblsan.la: $(liblsan_la_OBJECTS) $(liblsan_la_DEPENDENCIES) 
+	$(liblsan_la_LINK) $(am_liblsan_la_rpath) $(liblsan_la_OBJECTS) $(liblsan_la_LIBADD) $(LIBS)
 libsanitizer_lsan.la: $(libsanitizer_lsan_la_OBJECTS) $(libsanitizer_lsan_la_DEPENDENCIES) 
 	$(CXXLINK)  $(libsanitizer_lsan_la_OBJECTS) $(libsanitizer_lsan_la_LIBADD) $(LIBS)
 
@@ -312,8 +391,12 @@  mostlyclean-compile:
 distclean-compile:
 	-rm -f *.tab.c
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lsan.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lsan_allocator.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lsan_common.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lsan_common_linux.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lsan_interceptors.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lsan_thread.Plo@am__quote@
 
 .cc.o:
 @am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@@ -397,6 +480,9 @@  check-am: all-am
 check: check-am
 all-am: Makefile $(LTLIBRARIES)
 installdirs:
+	for dir in "$(DESTDIR)$(toolexeclibdir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
 install: install-am
 install-exec: install-exec-am
 install-data: install-data-am
@@ -425,7 +511,7 @@  maintainer-clean-generic:
 clean: clean-am
 
 clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
-	mostlyclean-am
+	clean-toolexeclibLTLIBRARIES mostlyclean-am
 
 distclean: distclean-am
 	-rm -rf ./$(DEPDIR)
@@ -451,7 +537,7 @@  install-dvi: install-dvi-am
 
 install-dvi-am:
 
-install-exec-am:
+install-exec-am: install-toolexeclibLTLIBRARIES
 
 install-html: install-html-am
 
@@ -491,22 +577,24 @@  ps: ps-am
 
 ps-am:
 
-uninstall-am:
+uninstall-am: uninstall-toolexeclibLTLIBRARIES
 
 .MAKE: install-am install-strip
 
 .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
-	clean-libtool clean-noinstLTLIBRARIES ctags distclean \
-	distclean-compile distclean-generic distclean-libtool \
-	distclean-tags dvi dvi-am html html-am info info-am 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 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
+	clean-libtool clean-noinstLTLIBRARIES \
+	clean-toolexeclibLTLIBRARIES ctags distclean distclean-compile \
+	distclean-generic distclean-libtool distclean-tags dvi dvi-am \
+	html html-am info info-am 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
 
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.