summaryrefslogtreecommitdiff
path: root/lib/asan
diff options
context:
space:
mode:
authorReid Kleckner <rnk@google.com>2016-03-23 20:45:52 +0000
committerReid Kleckner <rnk@google.com>2016-03-23 20:45:52 +0000
commite332fe7be0c3e41c38e2646cdd9fe7ccd595e67f (patch)
treefe601817402ecfa3928331e97a60739aeeaa4f85 /lib/asan
parenta7481bb501df457fe5d33e89abf36fa033c9e560 (diff)
[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. git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@264190 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/asan')
-rw-r--r--lib/asan/asan_malloc_win.cc17
-rw-r--r--lib/asan/asan_new_delete.cc18
2 files changed, 17 insertions, 18 deletions
diff --git a/lib/asan/asan_malloc_win.cc b/lib/asan/asan_malloc_win.cc
index ec74fd3a8..a525f717f 100644
--- a/lib/asan/asan_malloc_win.cc
+++ b/lib/asan/asan_malloc_win.cc
@@ -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@YAPAXI@Z", (uptr)op_new);
- __interception::OverrideFunction("??3@YAXPAX@Z", (uptr)op_delete);
- __interception::OverrideFunction("??_U@YAPAXI@Z", (uptr)op_array_new);
- __interception::OverrideFunction("??_V@YAXPAX@Z", (uptr)op_array_delete);
#endif
}
} // namespace __asan
diff --git a/lib/asan/asan_new_delete.cc b/lib/asan/asan_new_delete.cc
index b5ba13ef4..fef66041f 100644
--- a/lib/asan/asan_new_delete.cc
+++ b/lib/asan/asan_new_delete.cc
@@ -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@YAPEAX_K@Z") // operator new
+# pragma comment(linker, "/export:??3@YAXPEAX@Z") // operator delete
+# pragma comment(linker, "/export:??3@YAXPEAX_K@Z") // sized operator delete
+# pragma comment(linker, "/export:??_U@YAPEAX_K@Z") // operator new[]
+# pragma comment(linker, "/export:??_V@YAXPEAX@Z") // operator delete[]
+# else
+# pragma comment(linker, "/export:??2@YAPAXI@Z") // operator new
+# pragma comment(linker, "/export:??3@YAXPAX@Z") // operator delete
+# pragma comment(linker, "/export:??3@YAXPAXI@Z") // sized operator delete
+# pragma comment(linker, "/export:??_U@YAPAXI@Z") // operator new[]
+# pragma comment(linker, "/export:??_V@YAXPAX@Z") // operator delete[]
+# endif
#else
# define CXX_OPERATOR_ATTRIBUTE INTERCEPTOR_ATTRIBUTE
#endif