mstorsjo created this revision.
mstorsjo added a reviewer: rnk.

Linking to ASan for MinGW is similar to MSVC, but MinGW always links the CRT 
dynamically, so there is only one of the MSVC cases to consider.

When linking to a shared compiler runtime library on MinGW, the suffix of the 
import library is .dll.a.

The existing case of .dll as suffix for windows in general doesn't seem correct 
(since this is used for linking). As long as callers never actually set the 
Shared flag, the default static suffix of .lib also worked fine for import 
libraries as well.


Repository:
  rC Clang

https://reviews.llvm.org/D52538

Files:
  lib/Driver/ToolChain.cpp
  lib/Driver/ToolChains/MinGW.cpp
  lib/Driver/ToolChains/MinGW.h
  test/Driver/mingw-sanitizers.c

Index: test/Driver/mingw-sanitizers.c
===================================================================
--- /dev/null
+++ test/Driver/mingw-sanitizers.c
@@ -0,0 +1,11 @@
+// RUN: %clang -target i686-windows-gnu %s -### -fsanitize=address 2>&1 | FileCheck --check-prefix=ASAN-I686 %s
+// ASAN-I686: "{{.*}}libclang_rt.asan_dynamic-i386.dll.a"
+// ASAN-I686: "{{[^"]*}}libclang_rt.asan_dynamic_runtime_thunk-i386.a"
+// ASAN-I686: "--require-defined" "___asan_seh_interceptor"
+// ASAN-I686: "--whole-archive" "{{.*}}libclang_rt.asan_dynamic_runtime_thunk-i386.a" "--no-whole-archive"
+
+// RUN: %clang -target x86_64-windows-gnu %s -### -fsanitize=address 2>&1 | FileCheck --check-prefix=ASAN-X86_64 %s
+// ASAN-X86_64: "{{.*}}libclang_rt.asan_dynamic-x86_64.dll.a"
+// ASAN-X86_64: "{{[^"]*}}libclang_rt.asan_dynamic_runtime_thunk-x86_64.a"
+// ASAN-X86_64: "--require-defined" "__asan_seh_interceptor"
+// ASAN-X86_64: "--whole-archive" "{{.*}}libclang_rt.asan_dynamic_runtime_thunk-x86_64.a" "--no-whole-archive"
Index: lib/Driver/ToolChains/MinGW.h
===================================================================
--- lib/Driver/ToolChains/MinGW.h
+++ lib/Driver/ToolChains/MinGW.h
@@ -65,6 +65,8 @@
   bool isPIEDefault() const override;
   bool isPICDefaultForced() const override;
 
+  SanitizerMask getSupportedSanitizers() const override;
+
   llvm::ExceptionHandling GetExceptionModel(
       const llvm::opt::ArgList &Args) const override;
 
Index: lib/Driver/ToolChains/MinGW.cpp
===================================================================
--- lib/Driver/ToolChains/MinGW.cpp
+++ lib/Driver/ToolChains/MinGW.cpp
@@ -14,6 +14,7 @@
 #include "clang/Driver/Driver.h"
 #include "clang/Driver/DriverDiagnostic.h"
 #include "clang/Driver/Options.h"
+#include "clang/Driver/SanitizerArgs.h"
 #include "llvm/Option/ArgList.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Path.h"
@@ -95,7 +96,7 @@
                                         const char *LinkingOutput) const {
   const ToolChain &TC = getToolChain();
   const Driver &D = TC.getDriver();
-  // const SanitizerArgs &Sanitize = TC.getSanitizerArgs();
+  const SanitizerArgs &Sanitize = TC.getSanitizerArgs();
 
   ArgStringList CmdArgs;
 
@@ -187,8 +188,6 @@
   TC.AddFilePathLibArgs(Args, CmdArgs);
   AddLinkerInputs(TC, Inputs, Args, CmdArgs, JA);
 
-  // TODO: Add ASan stuff here
-
   // TODO: Add profile stuff here
 
   if (TC.ShouldLinkCXXStdlib(Args)) {
@@ -231,6 +230,24 @@
       if (Args.hasArg(options::OPT_pthread))
         CmdArgs.push_back("-lpthread");
 
+      if (Sanitize.needsAsanRt()) {
+        // MinGW always links against a shared CRT.
+        CmdArgs.push_back(
+            TC.getCompilerRTArgString(Args, "asan_dynamic", true));
+        CmdArgs.push_back(
+            TC.getCompilerRTArgString(Args, "asan_dynamic_runtime_thunk"));
+        CmdArgs.push_back(Args.MakeArgString("--require-defined"));
+        CmdArgs.push_back(Args.MakeArgString(TC.getArch() == llvm::Triple::x86
+                                                 ? "___asan_seh_interceptor"
+                                                 : "__asan_seh_interceptor"));
+        // Make sure the linker consider all object files from the dynamic
+        // runtime thunk.
+        CmdArgs.push_back(Args.MakeArgString("--whole-archive"));
+        CmdArgs.push_back(Args.MakeArgString(
+            TC.getCompilerRT(Args, "asan_dynamic_runtime_thunk")));
+        CmdArgs.push_back(Args.MakeArgString("--no-whole-archive"));
+      }
+
       if (!HasWindowsApp) {
         // Add system libraries. If linking to libwindowsapp.a, that import
         // library replaces all these and we shouldn't accidentally try to
@@ -407,6 +424,12 @@
   return llvm::ExceptionHandling::DwarfCFI;
 }
 
+SanitizerMask toolchains::MinGW::getSupportedSanitizers() const {
+  SanitizerMask Res = ToolChain::getSupportedSanitizers();
+  Res |= SanitizerKind::Address;
+  return Res;
+}
+
 void toolchains::MinGW::AddCudaIncludeArgs(const ArgList &DriverArgs,
                                            ArgStringList &CC1Args) const {
   CudaInstallation.AddCudaIncludeArgs(DriverArgs, CC1Args);
Index: lib/Driver/ToolChain.cpp
===================================================================
--- lib/Driver/ToolChain.cpp
+++ lib/Driver/ToolChain.cpp
@@ -367,7 +367,9 @@
       TT.isWindowsMSVCEnvironment() || TT.isWindowsItaniumEnvironment();
 
   const char *Prefix = IsITANMSVCWindows ? "" : "lib";
-  const char *Suffix = Shared ? (Triple.isOSWindows() ? ".dll" : ".so")
+  const char *Suffix = Shared ? (Triple.isWindowsGNUEnvironment()
+                                     ? ".dll.a"
+                                     : Triple.isOSWindows() ? ".lib" : ".so")
                               : (IsITANMSVCWindows ? ".lib" : ".a");
 
   for (const auto &LibPath : getLibraryPaths()) {
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to