[compiler-rt] r264190 - [asan] Export new and delete operators on Windows

Reid Kleckner via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 23 13:45:52 PDT 2016


Author: rnk
Date: Wed Mar 23 15:45:52 2016
New Revision: 264190

URL: http://llvm.org/viewvc/llvm-project?rev=264190&view=rev
Log:
[asan] Export new and delete operators on Windows

This is necessary to support the dynamic CRT (/MD) with VS2015. In
VS2015, these symbols are no longer imported from a DLL, they provided
statically by msvcrt.lib. This means our approach of hotpatching the DLL
no longer works.

By exporting the symbols, we end up relying on the same mechanism that
we use to intercept symbols in the static CRT (/MT) case. The ASan
runtime always needs to appear first on the link line, and the linker
searches for symbol definitions from left to right. This means we can
stop hotpatching operator new and delete in the CRT, which is nice.

I think that the only reason we weren't exporting the symbols already is
because MSVC doesn't allow you to do it directly with
__declspec(dllexport). Instead, we can use
`#pragma comment(linker, "/export:foo")`, which is most of what the
attribute does under the hood. It does mean we have to write down the
mangled names of the operators, but that's not too bad.

Modified:
    compiler-rt/trunk/lib/asan/asan_malloc_win.cc
    compiler-rt/trunk/lib/asan/asan_new_delete.cc

Modified: compiler-rt/trunk/lib/asan/asan_malloc_win.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_malloc_win.cc?rev=264190&r1=264189&r2=264190&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_malloc_win.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_malloc_win.cc Wed Mar 23 15:45:52 2016
@@ -174,23 +174,6 @@ void ReplaceSystemMalloc() {
   __interception::OverrideFunction("_recalloc_crt", (uptr)_recalloc);
   __interception::OverrideFunction("_msize", (uptr)_msize);
   __interception::OverrideFunction("_expand", (uptr)_expand);
-
-  // Override different versions of 'operator new' and 'operator delete'.
-  // No need to override the nothrow versions as they just wrap the throw
-  // versions.
-  // FIXME: Unfortunately, MSVC miscompiles the statements that take the
-  // addresses of the array versions of these operators,
-  // see https://connect.microsoft.com/VisualStudio/feedbackdetail/view/946992
-  // We might want to try to work around this by [inline] assembly or compiling
-  // parts of the RTL with Clang.
-  void *(*op_new)(size_t sz) = operator new;
-  void (*op_delete)(void *p) = operator delete;
-  void *(*op_array_new)(size_t sz) = operator new[];
-  void (*op_array_delete)(void *p) = operator delete[];
-  __interception::OverrideFunction("??2 at YAPAXI@Z", (uptr)op_new);
-  __interception::OverrideFunction("??3 at YAXPAX@Z", (uptr)op_delete);
-  __interception::OverrideFunction("??_U at YAPAXI@Z", (uptr)op_array_new);
-  __interception::OverrideFunction("??_V at YAXPAX@Z", (uptr)op_array_delete);
 #endif
 }
 }  // namespace __asan

Modified: compiler-rt/trunk/lib/asan/asan_new_delete.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_new_delete.cc?rev=264190&r1=264189&r2=264190&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_new_delete.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_new_delete.cc Wed Mar 23 15:45:52 2016
@@ -20,9 +20,25 @@
 
 #include <stddef.h>
 
-// C++ operators can't have visibility attributes on Windows.
+// C++ operators can't have dllexport attributes on Windows. We export them
+// anyway by passing extra -export flags to the linker, which is exactly that
+// dllexport would normally do. We need to export them in order to make the
+// VS2015 dynamic CRT (MD) work.
 #if SANITIZER_WINDOWS
 # define CXX_OPERATOR_ATTRIBUTE
+# ifdef _WIN64
+#  pragma comment(linker, "/export:??2 at YAPEAX_K@Z")   // operator new
+#  pragma comment(linker, "/export:??3 at YAXPEAX@Z")    // operator delete
+#  pragma comment(linker, "/export:??3 at YAXPEAX_K@Z")  // sized operator delete
+#  pragma comment(linker, "/export:??_U at YAPEAX_K@Z")  // operator new[]
+#  pragma comment(linker, "/export:??_V at YAXPEAX@Z")   // operator delete[]
+# else
+#  pragma comment(linker, "/export:??2 at YAPAXI@Z")   // operator new
+#  pragma comment(linker, "/export:??3 at YAXPAX@Z")   // operator delete
+#  pragma comment(linker, "/export:??3 at YAXPAXI@Z")  // sized operator delete
+#  pragma comment(linker, "/export:??_U at YAPAXI@Z")  // operator new[]
+#  pragma comment(linker, "/export:??_V at YAXPAX@Z")  // operator delete[]
+# endif
 #else
 # define CXX_OPERATOR_ATTRIBUTE INTERCEPTOR_ATTRIBUTE
 #endif




More information about the llvm-commits mailing list