Hi! This patch adjusts -fsanitize=thread linking behavior to match that of -fsanitize=address, in that -ltsan is also linked early on the link command line, -ldl -lpthread is added on Linux, etc. Additionally, for -nostdlib or -nodefaultlibs this patch doesn't add -lasan nor -ltsan nor its dependencies, it is user's responsibility. The only important difference between -fsanitize=address and -fsanitize=thread is that while the former only rejects -static link, the latter (as it requires PIEs right now) only allows -shared or -pie links.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2013-02-05 Jakub Jelinek <ja...@redhat.com> PR sanitizer/55374 * config/gnu-user.h (LIBTSAN_EARLY_SPEC): Define. (STATIC_LIBTSAN_LIBS): Likewise. * gcc.c (ADD_STATIC_LIBTSAN_LIBS, LIBTSAN_EARLY_SPEC): Define. (LIBTSAN_SPEC): Add ADD_STATIC_LIBTSAN_LIBS, if LIBTSAN_EARLY_SPEC is defined, don't add anything else beyond that. (SANITIZER_EARLY_SPEC, SANITIZER_SPEC): Define. (LINK_COMMAND_SPEC): Use them. --- gcc/config/gnu-user.h.jj 2013-02-05 12:06:08.000000000 +0100 +++ gcc/config/gnu-user.h 2013-02-05 12:45:44.707178024 +0100 @@ -101,14 +101,22 @@ see the files COPYING3 and COPYING.RUNTI /* 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. */ + 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:" \ 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:" \ + LD_STATIC_OPTION " --whole-archive -ltsan --no-whole-archive " \ + LD_DYNAMIC_OPTION "}}%{!static-libtsan:-ltsan}" #endif /* Additional libraries needed by -static-libasan. */ #undef STATIC_LIBASAN_LIBS #define STATIC_LIBASAN_LIBS "-ldl -lpthread" + +/* Additional libraries needed by -static-libtsan. */ +#undef STATIC_LIBTSAN_LIBS +#define STATIC_LIBTSAN_LIBS "-ldl -lpthread" --- gcc/gcc.c.jj 2013-01-30 19:05:06.000000000 +0100 +++ gcc/gcc.c 2013-02-05 12:56:37.539108130 +0100 @@ -564,14 +564,27 @@ proper position among the other output f #endif #ifndef LIBTSAN_SPEC -#ifdef HAVE_LD_STATIC_DYNAMIC +#ifdef STATIC_LIBTSAN_LIBS +#define ADD_STATIC_LIBTSAN_LIBS \ + " %{static-libtsan:" STATIC_LIBTSAN_LIBS "}" +#else +#define ADD_STATIC_LIBTSAN_LIBS +#endif +#ifdef LIBTSAN_EARLY_SPEC +#define LIBTSAN_SPEC ADD_STATIC_LIBTSAN_LIBS +#elif defined(HAVE_LD_STATIC_DYNAMIC) #define LIBTSAN_SPEC "%{static-libtsan:" LD_STATIC_OPTION \ - "} -ltsan %{static-libtsan:" LD_DYNAMIC_OPTION "}" + "} -ltsan %{static-libtsan:" LD_DYNAMIC_OPTION "}" \ + ADD_STATIC_LIBTSAN_LIBS #else -#define LIBTSAN_SPEC "-ltsan" +#define LIBTSAN_SPEC "-ltsan" ADD_STATIC_LIBTSAN_LIBS #endif #endif +#ifndef LIBTSAN_EARLY_SPEC +#define LIBTSAN_EARLY_SPEC "" +#endif + /* config.h can define LIBGCC_SPEC to override how and when libgcc.a is included. */ #ifndef LIBGCC_SPEC @@ -691,6 +704,21 @@ proper position among the other output f %e-fuse-linker-plugin is not supported in this configuration}" #endif +/* Linker command line options for -fsanitize= early on the command line. */ +#ifndef SANITIZER_EARLY_SPEC +#define SANITIZER_EARLY_SPEC "\ +%{!nostdlib:%{!nodefaultlibs:%{fsanitize=address:" LIBASAN_EARLY_SPEC "} \ + %{fsanitize=thread:" LIBTSAN_EARLY_SPEC "}}}" +#endif + +/* Linker command line options for -fsanitize= late on the command line. */ +#ifndef SANITIZER_SPEC +#define SANITIZER_SPEC "\ +%{!nostdlib:%{!nodefaultlibs:%{fsanitize=address:" LIBASAN_SPEC "\ + %{static:%ecannot specify -static with -fsanitize=address}}\ + %{fsanitize=thread:" LIBTSAN_SPEC "\ + %{!pie:%{!shared:%e-fsanitize=thread linking must be done with -pie or -shared}}}}}" +#endif /* -u* was put back because both BSD and SysV seem to support it. */ /* %{static:} simply prevents an error message if the target machine @@ -706,19 +734,16 @@ proper position among the other output f %{!fsyntax-only:%{!c:%{!M:%{!MM:%{!E:%{!S:\ %(linker) " \ LINK_PLUGIN_SPEC \ - "%{flto|flto=*:%<fcompare-debug*} \ + "%{flto|flto=*:%<fcompare-debug*} \ %{flto} %{flto=*} %l " LINK_PIE_SPEC \ "%{fuse-ld=*:-fuse-ld=%*}\ %X %{o*} %{e*} %{N} %{n} %{r}\ %{s} %{t} %{u*} %{z} %{Z} %{!nostdlib:%{!nostartfiles:%S}}\ - %{static:} %{L*} %(mfwrap) %(link_libgcc) \ - %{fsanitize=address:" LIBASAN_EARLY_SPEC "} %o\ + %{static:} %{L*} %(mfwrap) %(link_libgcc) " SANITIZER_EARLY_SPEC " %o\ %{fopenmp|ftree-parallelize-loops=*:%:include(libgomp.spec)%(link_gomp)}\ %{fgnu-tm:%:include(libitm.spec)%(link_itm)}\ %(mflib) " STACK_SPLIT_SPEC "\ - %{fprofile-arcs|fprofile-generate*|coverage:-lgcov}\ - %{fsanitize=address:" LIBASAN_SPEC "%{static:%ecannot specify -static with -fsanitize=address}}\ - %{fsanitize=thread:" LIBTSAN_SPEC "}\ + %{fprofile-arcs|fprofile-generate*|coverage:-lgcov} " SANITIZER_SPEC " \ %{!nostdlib:%{!nodefaultlibs:%(link_ssp) %(link_gcc_c_sequence)}}\ %{!nostdlib:%{!nostartfiles:%E}} %{T*} }}}}}}" #endif Jakub