summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Storsjo <martin@martin.st>2018-10-01 20:53:25 +0000
committerMartin Storsjo <martin@martin.st>2018-10-01 20:53:25 +0000
commit9c8479bf2d8835bcae6ff3b8abdba49cb2096969 (patch)
tree2a2f168a172e6de018398738c6078801963ba4d9
parenta54982bd48aace7110b67d3b5c798834d2e0044d (diff)
[MinGW] Allow using ASan
Linking to ASan for MinGW is similar to MSVC, but MinGW always links the MSVCRT 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. Differential Revision: https://reviews.llvm.org/D52538
-rw-r--r--clang/lib/Driver/ToolChain.cpp4
-rw-r--r--clang/lib/Driver/ToolChains/MinGW.cpp29
-rw-r--r--clang/lib/Driver/ToolChains/MinGW.h2
-rw-r--r--clang/test/Driver/mingw-sanitizers.c11
4 files changed, 42 insertions, 4 deletions
diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp
index 8933e905fce..f05c8a39823 100644
--- a/clang/lib/Driver/ToolChain.cpp
+++ b/clang/lib/Driver/ToolChain.cpp
@@ -367,8 +367,10 @@ std::string ToolChain::getCompilerRT(const ArgList &Args, StringRef Component,
TT.isWindowsMSVCEnvironment() || TT.isWindowsItaniumEnvironment();
const char *Prefix = IsITANMSVCWindows ? "" : "lib";
- const char *Suffix = Shared ? (Triple.isOSWindows() ? ".dll" : ".so")
+ const char *Suffix = Shared ? (Triple.isOSWindows() ? ".lib" : ".so")
: (IsITANMSVCWindows ? ".lib" : ".a");
+ if (Shared && Triple.isWindowsGNUEnvironment())
+ Suffix = ".dll.a";
for (const auto &LibPath : getLibraryPaths()) {
SmallString<128> P(LibPath);
diff --git a/clang/lib/Driver/ToolChains/MinGW.cpp b/clang/lib/Driver/ToolChains/MinGW.cpp
index a88e00f0c8e..f9e641e63ff 100644
--- a/clang/lib/Driver/ToolChains/MinGW.cpp
+++ b/clang/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 @@ void tools::MinGW::Linker::ConstructJob(Compilation &C, const JobAction &JA,
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 @@ void tools::MinGW::Linker::ConstructJob(Compilation &C, const JobAction &JA,
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 @@ void tools::MinGW::Linker::ConstructJob(Compilation &C, const JobAction &JA,
if (Args.hasArg(options::OPT_pthread))
CmdArgs.push_back("-lpthread");
+ if (Sanitize.needsAsanRt()) {
+ // MinGW always links against a shared MSVCRT.
+ 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 @@ toolchains::MinGW::GetExceptionModel(const ArgList &Args) const {
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);
diff --git a/clang/lib/Driver/ToolChains/MinGW.h b/clang/lib/Driver/ToolChains/MinGW.h
index 0c3919d29f7..450044d4512 100644
--- a/clang/lib/Driver/ToolChains/MinGW.h
+++ b/clang/lib/Driver/ToolChains/MinGW.h
@@ -65,6 +65,8 @@ public:
bool isPIEDefault() const override;
bool isPICDefaultForced() const override;
+ SanitizerMask getSupportedSanitizers() const override;
+
llvm::ExceptionHandling GetExceptionModel(
const llvm::opt::ArgList &Args) const override;
diff --git a/clang/test/Driver/mingw-sanitizers.c b/clang/test/Driver/mingw-sanitizers.c
new file mode 100644
index 00000000000..09f28fea8ab
--- /dev/null
+++ b/clang/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"