alvinhochun created this revision.
alvinhochun added reviewers: mstorsjo, MaskRay.
Herald added a project: All.
alvinhochun requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

As stated in https://github.com/llvm/llvm-project/issues/61685, by
passing LLD the import lib of the asan DLL first, the asan DLL will be
listed as the first entry in the Import Directory Table, making it be
loaded first before other user DLLs. This allows asan to be initialized
as early as possible to increase its instrumentation coverage to include
other DLLs not built with asan.

This also avoids some false asan reports on `realloc` for memory
allocated during initialization of user DLLs being loaded earlier than
asan, because after this change they will be loaded later than asan.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D146908

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


Index: clang/test/Driver/mingw-sanitizers.c
===================================================================
--- clang/test/Driver/mingw-sanitizers.c
+++ clang/test/Driver/mingw-sanitizers.c
@@ -1,13 +1,18 @@
-// 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"
+// RUN: echo -n > %t.a
+// RUN: %clang -target i686-windows-gnu %s -### -fsanitize=address -lcomponent 
%t.a 2>&1 | FileCheck --check-prefixes=ASAN-ALL,ASAN-I686 -DINPUT=%t.a %s
+// RUN: %clang -target x86_64-windows-gnu %s -### -fsanitize=address 
-lcomponent %t.a 2>&1 | FileCheck --check-prefixes=ASAN-ALL,ASAN-X86_64 
-DINPUT=%t.a %s
+//
+// ASAN-ALL-NOT:"-l{{[^"]+"]}}"
+// ASAN-ALL-NOT:"[[INPUT]]"
+// 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"
+// 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"
+// ASAN-X86_64: "--whole-archive" 
"{{[^"]*}}libclang_rt.asan_dynamic_runtime_thunk-x86_64.a" "--no-whole-archive"
+// ASAN-ALL:    "-lcomponent"
+// ASAN-ALL:    "[[INPUT]]"
 
 // RUN: %clang -target x86_64-windows-gnu %s -### -fsanitize=vptr
Index: clang/lib/Driver/ToolChains/MinGW.cpp
===================================================================
--- clang/lib/Driver/ToolChains/MinGW.cpp
+++ clang/lib/Driver/ToolChains/MinGW.cpp
@@ -200,6 +200,29 @@
   Args.AddAllArgs(CmdArgs, options::OPT_u_Group);
   Args.AddLastArg(CmdArgs, options::OPT_Z_Flag);
 
+  // Add asan flags before other libs and objects. Making asan_dynamic the 
first
+  // import lib allows asan to be initialized as early as possible to increase
+  // its instrumentation coverage to include other user DLLs which has not been
+  // built with asan.
+  if (Sanitize.needsAsanRt() && !Args.hasArg(options::OPT_nostdlib) &&
+      !Args.hasArg(options::OPT_nodefaultlibs)) {
+    // MinGW always links against a shared MSVCRT.
+    CmdArgs.push_back(
+        TC.getCompilerRTArgString(Args, "asan_dynamic", ToolChain::FT_Shared));
+    CmdArgs.push_back(
+        TC.getCompilerRTArgString(Args, "asan_dynamic_runtime_thunk"));
+    CmdArgs.push_back("--require-defined");
+    CmdArgs.push_back(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("--whole-archive");
+    CmdArgs.push_back(
+        TC.getCompilerRTArgString(Args, "asan_dynamic_runtime_thunk"));
+    CmdArgs.push_back("--no-whole-archive");
+  }
+
   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
     if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_mdll)) {
       CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("dllcrt2.o")));
@@ -292,24 +315,6 @@
       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",
-                                                    ToolChain::FT_Shared));
-        CmdArgs.push_back(
-            TC.getCompilerRTArgString(Args, "asan_dynamic_runtime_thunk"));
-        CmdArgs.push_back("--require-defined");
-        CmdArgs.push_back(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("--whole-archive");
-        CmdArgs.push_back(
-            TC.getCompilerRTArgString(Args, "asan_dynamic_runtime_thunk"));
-        CmdArgs.push_back("--no-whole-archive");
-      }
-
       TC.addProfileRTLibs(Args, CmdArgs);
 
       if (!HasWindowsApp) {


Index: clang/test/Driver/mingw-sanitizers.c
===================================================================
--- clang/test/Driver/mingw-sanitizers.c
+++ clang/test/Driver/mingw-sanitizers.c
@@ -1,13 +1,18 @@
-// 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"
+// RUN: echo -n > %t.a
+// RUN: %clang -target i686-windows-gnu %s -### -fsanitize=address -lcomponent %t.a 2>&1 | FileCheck --check-prefixes=ASAN-ALL,ASAN-I686 -DINPUT=%t.a %s
+// RUN: %clang -target x86_64-windows-gnu %s -### -fsanitize=address -lcomponent %t.a 2>&1 | FileCheck --check-prefixes=ASAN-ALL,ASAN-X86_64 -DINPUT=%t.a %s
+//
+// ASAN-ALL-NOT:"-l{{[^"]+"]}}"
+// ASAN-ALL-NOT:"[[INPUT]]"
+// 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"
+// 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"
+// ASAN-X86_64: "--whole-archive" "{{[^"]*}}libclang_rt.asan_dynamic_runtime_thunk-x86_64.a" "--no-whole-archive"
+// ASAN-ALL:    "-lcomponent"
+// ASAN-ALL:    "[[INPUT]]"
 
 // RUN: %clang -target x86_64-windows-gnu %s -### -fsanitize=vptr
Index: clang/lib/Driver/ToolChains/MinGW.cpp
===================================================================
--- clang/lib/Driver/ToolChains/MinGW.cpp
+++ clang/lib/Driver/ToolChains/MinGW.cpp
@@ -200,6 +200,29 @@
   Args.AddAllArgs(CmdArgs, options::OPT_u_Group);
   Args.AddLastArg(CmdArgs, options::OPT_Z_Flag);
 
+  // Add asan flags before other libs and objects. Making asan_dynamic the first
+  // import lib allows asan to be initialized as early as possible to increase
+  // its instrumentation coverage to include other user DLLs which has not been
+  // built with asan.
+  if (Sanitize.needsAsanRt() && !Args.hasArg(options::OPT_nostdlib) &&
+      !Args.hasArg(options::OPT_nodefaultlibs)) {
+    // MinGW always links against a shared MSVCRT.
+    CmdArgs.push_back(
+        TC.getCompilerRTArgString(Args, "asan_dynamic", ToolChain::FT_Shared));
+    CmdArgs.push_back(
+        TC.getCompilerRTArgString(Args, "asan_dynamic_runtime_thunk"));
+    CmdArgs.push_back("--require-defined");
+    CmdArgs.push_back(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("--whole-archive");
+    CmdArgs.push_back(
+        TC.getCompilerRTArgString(Args, "asan_dynamic_runtime_thunk"));
+    CmdArgs.push_back("--no-whole-archive");
+  }
+
   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
     if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_mdll)) {
       CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("dllcrt2.o")));
@@ -292,24 +315,6 @@
       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",
-                                                    ToolChain::FT_Shared));
-        CmdArgs.push_back(
-            TC.getCompilerRTArgString(Args, "asan_dynamic_runtime_thunk"));
-        CmdArgs.push_back("--require-defined");
-        CmdArgs.push_back(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("--whole-archive");
-        CmdArgs.push_back(
-            TC.getCompilerRTArgString(Args, "asan_dynamic_runtime_thunk"));
-        CmdArgs.push_back("--no-whole-archive");
-      }
-
       TC.addProfileRTLibs(Args, CmdArgs);
 
       if (!HasWindowsApp) {
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to