[PATCH] D30219: [compiler-rt][asan] Fix incorrect macro preventing ICF with MSVC

Etienne Bergeron via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 21 11:18:55 PST 2017


etienneb created this revision.
Herald added subscribers: dberris, kubamracek.

The DLL thunk is a stub added into an instrumented DLL to redirect calls
to the real ones in the main executable. There thunks must contains dummy
code before __asan_init got called. Unfortunately, MSVC is doing ICF and is
merging functions with the same body.

In our case, this two ASAN thunks were merged:

  asan_interface.inc:16
  INTERFACE_FUNCTION(__asan_before_dynamic_init)

  sanitizer_common_interface.inc:16
  INTERFACE_FUNCTION(__sanitizer_verify_contiguous_container)

The problem is caused by the macro that is only using __LINE__ to prevent
collapsing code.

  #define INTERCEPT_SANITIZER_FUNCTION(name)
    extern "C" __declspec(noinline) void name() {
    volatile int prevent_icf = (__LINE__ << 8); (void)prevent_icf;

The current patch is adding __COUNTER__ which is safer than line.

But, to precent ICF (guarantee that code is different), we are using a unique attribute:

- the name of the function


https://reviews.llvm.org/D30219

Files:
  lib/sanitizer_common/sanitizer_win_dll_thunk.h


Index: lib/sanitizer_common/sanitizer_win_dll_thunk.h
===================================================================
--- lib/sanitizer_common/sanitizer_win_dll_thunk.h
+++ lib/sanitizer_common/sanitizer_win_dll_thunk.h
@@ -53,7 +53,11 @@
 // after __asan_init, thus an empty implementation is sufficient.
 #define INTERCEPT_SANITIZER_FUNCTION(name)                                     \
   extern "C" __declspec(noinline) void name() {                                \
-    volatile int prevent_icf = (__LINE__ << 8); (void)prevent_icf;             \
+    volatile int prevent_icf = (__LINE__ << 8) ^ __COUNTER__;                  \
+    static const char function_name[] = #name;                                 \
+    for (const char* ptr = &function_name[0]; *ptr; ++ptr)                     \
+      prevent_icf ^= *ptr;                                                     \
+    (void)prevent_icf;                                                         \
     __debugbreak();                                                            \
   }                                                                            \
   INTERCEPT_OR_DIE(#name, name)
@@ -64,7 +68,11 @@
 // we consider the default impl provided by asan library.
 #define INTERCEPT_SANITIZER_WEAK_FUNCTION(name)                                \
   extern "C" __declspec(noinline) void name() {                                \
-    volatile int prevent_icf = (__LINE__ << 8); (void)prevent_icf;             \
+    volatile int prevent_icf = (__LINE__ << 8) ^ __COUNTER__;                  \
+    static const char function_name[] = #name;                                 \
+    for (const char* ptr = &function_name[0]; *ptr; ++ptr)                     \
+      prevent_icf ^= *ptr;                                                     \
+    (void)prevent_icf;                                                         \
     __debugbreak();                                                            \
   }                                                                            \
   INTERCEPT_WHEN_POSSIBLE(#name, STRINGIFY(WEAK_EXPORT_NAME(name)), name)


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D30219.89251.patch
Type: text/x-patch
Size: 2136 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170221/03dd8f43/attachment.bin>


More information about the llvm-commits mailing list