[PATCH] [ASan/Win] Fix PR22545 __asan_unregister_globals is not called when using -MD runtimes

Timur Iskhodzhanov timurrrr at google.com
Tue Feb 17 07:00:56 PST 2015


http://reviews.llvm.org/D7597

Files:
  lib/Transforms/Instrumentation/AddressSanitizer.cpp
  test/Instrumentation/AddressSanitizer/instrument_global.ll

Index: lib/Transforms/Instrumentation/AddressSanitizer.cpp
===================================================================
--- lib/Transforms/Instrumentation/AddressSanitizer.cpp
+++ lib/Transforms/Instrumentation/AddressSanitizer.cpp
@@ -1272,16 +1272,26 @@
                   ConstantInt::get(IntptrTy, n));
 
   // We also need to unregister globals at the end, e.g. when a shared library
-  // gets closed.
+  // gets closed, by using global_dtors.
   Function *AsanDtorFunction = Function::Create(
       FunctionType::get(Type::getVoidTy(*C), false),
       GlobalValue::InternalLinkage, kAsanModuleDtorName, &M);
   BasicBlock *AsanDtorBB = BasicBlock::Create(*C, "", AsanDtorFunction);
   IRBuilder<> IRB_Dtor(ReturnInst::Create(*C, AsanDtorBB));
   IRB_Dtor.CreateCall2(AsanUnregisterGlobals,
                        IRB.CreatePointerCast(AllGlobals, IntptrTy),
                        ConstantInt::get(IntptrTy, n));
-  appendToGlobalDtors(M, AsanDtorFunction, kAsanCtorAndDtorPriority);
+  // MSVC CRT doesn't call LLVM global_dtors, so we have to use atexit()
+  // to work around (See PR22545).
+  if (TargetTriple.isKnownWindowsMSVCEnvironment() ||
+      TargetTriple.isWindowsItaniumEnvironment()) {
+    Function *AtExit = checkInterfaceFunction(M.getOrInsertFunction(
+      "atexit", IRB.getInt32Ty(), AsanDtorFunction->getType(), nullptr));
+    AtExit->setLinkage(Function::ExternalLinkage);
+    IRB.CreateCall(AtExit, AsanDtorFunction);
+  } else {
+    appendToGlobalDtors(M, AsanDtorFunction, kAsanCtorAndDtorPriority);
+  }
 
   DEBUG(dbgs() << M);
   return true;
Index: test/Instrumentation/AddressSanitizer/instrument_global.ll
===================================================================
--- test/Instrumentation/AddressSanitizer/instrument_global.ll
+++ test/Instrumentation/AddressSanitizer/instrument_global.ll
@@ -1,14 +1,15 @@
-; RUN: opt < %s -asan -asan-module -S | FileCheck %s
+; RUN: opt < %s -mtriple x86_64-unknown-linux-gnu -asan -asan-module -S | FileCheck %s --check-prefix=CHECK --check-prefix=LINUX
+; RUN: opt < %s -mtriple i686-pc-windows-msvc -asan -asan-module -S | FileCheck %s --check-prefix=CHECK --check-prefix=WIN32
 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
-target triple = "x86_64-unknown-linux-gnu"
 @xxx = global i32 0, align 4
 
 ; If a global is present, __asan_[un]register_globals should be called from
 ; module ctor/dtor
 
 ; CHECK: llvm.global_ctors
 ; CHECK: @__asan_gen_ = private constant [8 x i8] c"<stdin>\00", align 1
-; CHECK: llvm.global_dtors
+; LINUX: llvm.global_dtors
+; WIN32-NOT: llvm.global_dtors
 
 ; Test that we don't instrument global arrays with static initializer
 ; indexed with constants in-bounds. But instrument all other cases.
@@ -74,9 +75,9 @@
 ; CHECK-LABEL: define internal void @asan.module_ctor
 ; CHECK-NOT: ret
 ; CHECK: call void @__asan_register_globals
-; CHECK: ret
+; WIN32-NEXT: call i32 @atexit(void ()* @asan.module_dtor)
+; CHECK-NEXT: ret
 
 ; CHECK-LABEL: define internal void @asan.module_dtor
-; CHECK-NOT: ret
-; CHECK: call void @__asan_unregister_globals
-; CHECK: ret
+; CHECK-NEXT: call void @__asan_unregister_globals
+; CHECK-NEXT: ret

EMAIL PREFERENCES
  http://reviews.llvm.org/settings/panel/emailpreferences/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D7597.20082.patch
Type: text/x-patch
Size: 3290 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150217/35082f2c/attachment.bin>


More information about the llvm-commits mailing list