[PATCH] D52119: [SanitizerCoverage] Prevent /OPT:REF from stripping constructors

Jonathan Metzman via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 12 11:13:39 PDT 2018


This revision was automatically updated to reflect the committed changes.
Closed by commit rL344391: [SanitizerCoverage] Prevent /OPT:REF from stripping constructors (authored by metzman, committed by ).
Herald added subscribers: llvm-commits, delcypher.

Changed prior to commit:
  https://reviews.llvm.org/D52119?vs=169428&id=169465#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D52119

Files:
  compiler-rt/trunk/test/fuzzer/windows-opt-ref.test
  llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp


Index: compiler-rt/trunk/test/fuzzer/windows-opt-ref.test
===================================================================
--- compiler-rt/trunk/test/fuzzer/windows-opt-ref.test
+++ compiler-rt/trunk/test/fuzzer/windows-opt-ref.test
@@ -0,0 +1,9 @@
+REQUIRES: windows
+// Verify that the linker eliminating unreferenced functions (/OPT:REF) does not
+// strip sancov module constructor.
+RUN: %cpp_compiler %S/SimpleCmpTest.cpp -o %t-SimpleCmpTest /link /OPT:REF
+
+RUN: not %run %t-SimpleCmpTest -seed=1 -runs=100000000 2>&1 | FileCheck %s
+
+CHECK-NOT: ERROR: no interesting inputs were found. Is the code instrumented for coverage? Exiting.
+CHECK: BINGO
Index: llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
===================================================================
--- llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
+++ llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
@@ -29,6 +29,7 @@
 #include "llvm/IR/Intrinsics.h"
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/MDBuilder.h"
+#include "llvm/IR/Mangler.h"
 #include "llvm/IR/Module.h"
 #include "llvm/IR/Type.h"
 #include "llvm/Support/CommandLine.h"
@@ -298,6 +299,26 @@
   } else {
     appendToGlobalCtors(M, CtorFunc, SanCtorAndDtorPriority);
   }
+
+  if (TargetTriple.getObjectFormat() == Triple::COFF) {
+    // In COFF files, if the contructors are set as COMDAT (they are because
+    // COFF supports COMDAT) and the linker flag /OPT:REF (strip unreferenced
+    // functions and data) is used, the constructors get stripped. To prevent
+    // this, give the constructors weak ODR linkage and tell the linker to
+    // always include the sancov constructor. This way the linker can
+    // deduplicate the constructors but always leave one copy.
+    CtorFunc->setLinkage(GlobalValue::WeakODRLinkage);
+    SmallString<20> PartialIncDirective("/include:");
+    // Get constructor's mangled name in order to support i386.
+    SmallString<40> MangledName;
+    Mangler().getNameWithPrefix(MangledName, CtorFunc, true);
+    Twine IncDirective = PartialIncDirective + MangledName;
+    Metadata *Args[1] = {MDString::get(*C, IncDirective.str())};
+    MDNode *MetadataNode = MDNode::get(*C, Args);
+    NamedMDNode *NamedMetadata =
+        M.getOrInsertNamedMetadata("llvm.linker.options");
+    NamedMetadata->addOperand(MetadataNode);
+  }
   return CtorFunc;
 }
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D52119.169465.patch
Type: text/x-patch
Size: 2406 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20181012/1c81aa2a/attachment.bin>


More information about the llvm-commits mailing list