This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG421215b919d0: [SanitizerBinaryMetadata] Support ignore list 
(authored by melver).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D143664/new/

https://reviews.llvm.org/D143664

Files:
  clang/include/clang/Basic/CodeGenOptions.h
  clang/include/clang/Basic/DiagnosticDriverKinds.td
  clang/include/clang/Driver/Options.td
  clang/include/clang/Driver/SanitizerArgs.h
  clang/lib/CodeGen/BackendUtil.cpp
  clang/lib/Driver/SanitizerArgs.cpp
  clang/test/CodeGen/sanitize-metadata-ignorelist.c
  clang/test/Driver/fsanitize-metadata-ignorelist.c
  llvm/include/llvm/Transforms/Instrumentation/SanitizerBinaryMetadata.h
  llvm/lib/Transforms/Instrumentation/SanitizerBinaryMetadata.cpp

Index: llvm/lib/Transforms/Instrumentation/SanitizerBinaryMetadata.cpp
===================================================================
--- llvm/lib/Transforms/Instrumentation/SanitizerBinaryMetadata.cpp
+++ llvm/lib/Transforms/Instrumentation/SanitizerBinaryMetadata.cpp
@@ -38,13 +38,16 @@
 #include "llvm/Support/Allocator.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Debug.h"
+#include "llvm/Support/SpecialCaseList.h"
 #include "llvm/Support/StringSaver.h"
+#include "llvm/Support/VirtualFileSystem.h"
 #include "llvm/TargetParser/Triple.h"
 #include "llvm/Transforms/Instrumentation.h"
 #include "llvm/Transforms/Utils/ModuleUtils.h"
 
 #include <array>
 #include <cstdint>
+#include <memory>
 
 using namespace llvm;
 
@@ -121,9 +124,11 @@
 
 class SanitizerBinaryMetadata {
 public:
-  SanitizerBinaryMetadata(Module &M, SanitizerBinaryMetadataOptions Opts)
+  SanitizerBinaryMetadata(Module &M, SanitizerBinaryMetadataOptions Opts,
+                          std::unique_ptr<SpecialCaseList> Ignorelist)
       : Mod(M), Options(transformOptionsFromCl(std::move(Opts))),
-        TargetTriple(M.getTargetTriple()), IRB(M.getContext()) {
+        Ignorelist(std::move(Ignorelist)), TargetTriple(M.getTargetTriple()),
+        IRB(M.getContext()) {
     // FIXME: Make it work with other formats.
     assert(TargetTriple.isOSBinFormatELF() && "ELF only");
   }
@@ -168,6 +173,7 @@
 
   Module &Mod;
   const SanitizerBinaryMetadataOptions Options;
+  std::unique_ptr<SpecialCaseList> Ignorelist;
   const Triple TargetTriple;
   IRBuilder<> IRB;
   BumpPtrAllocator Alloc;
@@ -243,6 +249,8 @@
     return;
   if (F.hasFnAttribute(Attribute::DisableSanitizerInstrumentation))
     return;
+  if (Ignorelist && Ignorelist->inSection("metadata", "fun", F.getName()))
+    return;
   // Don't touch available_externally functions, their actual body is elsewhere.
   if (F.getLinkage() == GlobalValue::AvailableExternallyLinkage)
     return;
@@ -455,12 +463,20 @@
 } // namespace
 
 SanitizerBinaryMetadataPass::SanitizerBinaryMetadataPass(
-    SanitizerBinaryMetadataOptions Opts)
-    : Options(std::move(Opts)) {}
+    SanitizerBinaryMetadataOptions Opts, ArrayRef<std::string> IgnorelistFiles)
+    : Options(std::move(Opts)), IgnorelistFiles(std::move(IgnorelistFiles)) {}
 
 PreservedAnalyses
 SanitizerBinaryMetadataPass::run(Module &M, AnalysisManager<Module> &AM) {
-  SanitizerBinaryMetadata Pass(M, Options);
+  std::unique_ptr<SpecialCaseList> Ignorelist;
+  if (!IgnorelistFiles.empty()) {
+    Ignorelist = SpecialCaseList::createOrDie(IgnorelistFiles,
+                                              *vfs::getRealFileSystem());
+    if (Ignorelist->inSection("metadata", "src", M.getSourceFileName()))
+      return PreservedAnalyses::all();
+  }
+
+  SanitizerBinaryMetadata Pass(M, Options, std::move(Ignorelist));
   if (Pass.run())
     return PreservedAnalyses::none();
   return PreservedAnalyses::all();
Index: llvm/include/llvm/Transforms/Instrumentation/SanitizerBinaryMetadata.h
===================================================================
--- llvm/include/llvm/Transforms/Instrumentation/SanitizerBinaryMetadata.h
+++ llvm/include/llvm/Transforms/Instrumentation/SanitizerBinaryMetadata.h
@@ -12,6 +12,7 @@
 #ifndef LLVM_TRANSFORMS_INSTRUMENTATION_SANITIZERBINARYMETADATA_H
 #define LLVM_TRANSFORMS_INSTRUMENTATION_SANITIZERBINARYMETADATA_H
 
+#include "llvm/ADT/ArrayRef.h"
 #include "llvm/IR/Function.h"
 #include "llvm/IR/Module.h"
 #include "llvm/IR/PassManager.h"
@@ -50,12 +51,14 @@
     : public PassInfoMixin<SanitizerBinaryMetadataPass> {
 public:
   explicit SanitizerBinaryMetadataPass(
-      SanitizerBinaryMetadataOptions Opts = {});
+      SanitizerBinaryMetadataOptions Opts = {},
+      ArrayRef<std::string> IgnorelistFiles = {});
   PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
   static bool isRequired() { return true; }
 
 private:
   const SanitizerBinaryMetadataOptions Options;
+  const ArrayRef<std::string> IgnorelistFiles;
 };
 
 } // namespace llvm
Index: clang/test/Driver/fsanitize-metadata-ignorelist.c
===================================================================
--- /dev/null
+++ clang/test/Driver/fsanitize-metadata-ignorelist.c
@@ -0,0 +1,14 @@
+// Verify Driver passes on -fsanitize-metadata-ignorelist.
+
+// RUN: echo "fun:foo" > %t.1
+// RUN: echo "fun:bar" > %t.2
+
+// RUN: %clang -target x86_64-linux-gnu -fexperimental-sanitize-metadata=all -fexperimental-sanitize-metadata-ignorelist=%t.1 -fexperimental-sanitize-metadata-ignorelist=%t.2 %s -### 2>&1 | FileCheck %s
+// RUN: %clang -target aarch64-linux-gnu -fexperimental-sanitize-metadata=atomics -fexperimental-sanitize-metadata-ignorelist=%t.1 -fexperimental-sanitize-metadata-ignorelist=%t.2 %s -### 2>&1 | FileCheck %s
+// CHECK: "-fexperimental-sanitize-metadata-ignorelist={{.*}}.1" "-fexperimental-sanitize-metadata-ignorelist={{.*}}.2"
+
+// Verify -fsanitize-metadata-ignorelist flag not passed if there is no -fsanitize-metadata flag.
+// RUN: %clang -target x86_64-linux-gnu -fexperimental-sanitize-metadata-ignorelist=%t.1 -fexperimental-sanitize-metadata-ignorelist=%t.2 %s -### 2>&1 | FileCheck %s --check-prefix=NOSANMD
+// RUN: %clang -target aarch64-linux-gnu -fexperimental-sanitize-metadata-ignorelist=%t.1 -fexperimental-sanitize-metadata-ignorelist=%t.2 %s -### 2>&1 | FileCheck %s --check-prefix=NOSANMD
+// NOSANMD: warning: argument unused during compilation: '-fexperimental-sanitize-metadata-ignorelist
+// NOSANMD-NOT: "-fexperimental-sanitize-metadata-ignorelist
Index: clang/test/CodeGen/sanitize-metadata-ignorelist.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/sanitize-metadata-ignorelist.c
@@ -0,0 +1,55 @@
+// RUN: %clang -O -fexperimental-sanitize-metadata=all -target x86_64-gnu-linux -x c -S -emit-llvm %s -o - | FileCheck %s --check-prefixes=ALLOW
+// RUN: echo "fun:foo" > %t.fun
+// RUN: %clang -O -fexperimental-sanitize-metadata=all -fexperimental-sanitize-metadata-ignorelist=%t.fun -target x86_64-gnu-linux -x c -S -emit-llvm %s -o - | FileCheck %s --check-prefixes=FUN
+// RUN: echo "src:%s" > %t.src
+// RUN: %clang -O -fexperimental-sanitize-metadata=all -fexperimental-sanitize-metadata-ignorelist=%t.src -target x86_64-gnu-linux -x c -S -emit-llvm %s -o - | FileCheck %s --check-prefixes=SRC
+
+int y;
+
+// ALLOW-LABEL: define {{[^@]+}}@foo
+// ALLOW-SAME: () local_unnamed_addr #[[ATTR0:[0-9]+]] !pcsections !5 {
+// ALLOW-NEXT:  entry:
+// ALLOW-NEXT:    [[TMP0:%.*]] = atomicrmw add ptr @y, i32 1 monotonic, align 4, !pcsections !7
+// ALLOW-NEXT:    ret void
+//
+// FUN-LABEL: define {{[^@]+}}@foo
+// FUN-SAME: () local_unnamed_addr #[[ATTR0:[0-9]+]] {
+// FUN-NEXT:  entry:
+// FUN-NEXT:    [[TMP0:%.*]] = atomicrmw add ptr @y, i32 1 monotonic, align 4
+// FUN-NEXT:    ret void
+//
+// SRC-LABEL: define {{[^@]+}}@foo
+// SRC-SAME: () local_unnamed_addr #[[ATTR0:[0-9]+]] {
+// SRC-NEXT:  entry:
+// SRC-NEXT:    [[TMP0:%.*]] = atomicrmw add ptr @y, i32 1 monotonic, align 4
+// SRC-NEXT:    ret void
+//
+void foo() {
+  __atomic_fetch_add(&y, 1, __ATOMIC_RELAXED);
+}
+
+// ALLOW-LABEL: define {{[^@]+}}@bar
+// ALLOW-SAME: () local_unnamed_addr #[[ATTR0]] !pcsections !5 {
+// ALLOW-NEXT:  entry:
+// ALLOW-NEXT:    [[TMP0:%.*]] = atomicrmw add ptr @y, i32 2 monotonic, align 4, !pcsections !7
+// ALLOW-NEXT:    ret void
+//
+// FUN-LABEL: define {{[^@]+}}@bar
+// FUN-SAME: () local_unnamed_addr #[[ATTR0]] !pcsections !5 {
+// FUN-NEXT:  entry:
+// FUN-NEXT:    [[TMP0:%.*]] = atomicrmw add ptr @y, i32 2 monotonic, align 4, !pcsections !7
+// FUN-NEXT:    ret void
+//
+// SRC-LABEL: define {{[^@]+}}@bar
+// SRC-SAME: () local_unnamed_addr #[[ATTR0]] {
+// SRC-NEXT:  entry:
+// SRC-NEXT:    [[TMP0:%.*]] = atomicrmw add ptr @y, i32 2 monotonic, align 4
+// SRC-NEXT:    ret void
+//
+void bar() {
+  __atomic_fetch_add(&y, 2, __ATOMIC_RELAXED);
+}
+
+// ALLOW: __sanitizer_metadata_covered.module_ctor
+// FUN: __sanitizer_metadata_covered.module_ctor
+// SRC-NOT: __sanitizer_metadata_covered.module_ctor
Index: clang/lib/Driver/SanitizerArgs.cpp
===================================================================
--- clang/lib/Driver/SanitizerArgs.cpp
+++ clang/lib/Driver/SanitizerArgs.cpp
@@ -864,6 +864,16 @@
     }
   }
 
+  // Parse -fsanitize-metadata-ignorelist option if enabled.
+  if (BinaryMetadataFeatures) {
+    parseSpecialCaseListArg(
+        D, Args, BinaryMetadataIgnorelistFiles,
+        options::OPT_fexperimental_sanitize_metadata_ignorelist_EQ,
+        OptSpecifier(), // Cannot clear ignore list, only append.
+        clang::diag::err_drv_malformed_sanitizer_metadata_ignorelist,
+        DiagnoseErrors);
+  }
+
   SharedRuntime =
       Args.hasFlag(options::OPT_shared_libsan, options::OPT_static_libsan,
                    TC.getTriple().isAndroid() || TC.getTriple().isOSFuchsia() ||
@@ -1141,6 +1151,9 @@
       CmdArgs.push_back(
           Args.MakeArgString("-fexperimental-sanitize-metadata=" + F.second));
   }
+  addSpecialCaseListOpt(Args, CmdArgs,
+                        "-fexperimental-sanitize-metadata-ignorelist=",
+                        BinaryMetadataIgnorelistFiles);
 
   if (TC.getTriple().isOSWindows() && needsUbsanRt()) {
     // Instruct the code generator to embed linker directives in the object file
Index: clang/lib/CodeGen/BackendUtil.cpp
===================================================================
--- clang/lib/CodeGen/BackendUtil.cpp
+++ clang/lib/CodeGen/BackendUtil.cpp
@@ -665,7 +665,8 @@
 
     if (CodeGenOpts.hasSanitizeBinaryMetadata()) {
       MPM.addPass(SanitizerBinaryMetadataPass(
-          getSanitizerBinaryMetadataOptions(CodeGenOpts)));
+          getSanitizerBinaryMetadataOptions(CodeGenOpts),
+          CodeGenOpts.SanitizeMetadataIgnorelistFiles));
     }
 
     auto MSanPass = [&](SanitizerMask Mask, bool CompileKernel) {
Index: clang/include/clang/Driver/SanitizerArgs.h
===================================================================
--- clang/include/clang/Driver/SanitizerArgs.h
+++ clang/include/clang/Driver/SanitizerArgs.h
@@ -30,6 +30,7 @@
   std::vector<std::string> SystemIgnorelistFiles;
   std::vector<std::string> CoverageAllowlistFiles;
   std::vector<std::string> CoverageIgnorelistFiles;
+  std::vector<std::string> BinaryMetadataIgnorelistFiles;
   int CoverageFeatures = 0;
   int BinaryMetadataFeatures = 0;
   int MsanTrackOrigins = 0;
Index: clang/include/clang/Driver/Options.td
===================================================================
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -1756,6 +1756,10 @@
 def fno_experimental_sanitize_metadata_EQ : CommaJoined<["-"], "fno-experimental-sanitize-metadata=">,
   Group<f_Group>, Flags<[CoreOption]>,
   HelpText<"Disable emitting metadata for binary analysis sanitizers">;
+def fexperimental_sanitize_metadata_ignorelist_EQ : Joined<["-"], "fexperimental-sanitize-metadata-ignorelist=">,
+    Group<f_Group>, Flags<[CoreOption]>,
+    HelpText<"Disable sanitizer metadata for modules and functions that match the provided special case list">,
+    MarshallingInfoStringVector<CodeGenOpts<"SanitizeMetadataIgnorelistFiles">>;
 def fsanitize_memory_track_origins_EQ : Joined<["-"], "fsanitize-memory-track-origins=">,
                                         Group<f_clang_Group>,
                                         HelpText<"Enable origins tracking in MemorySanitizer">,
Index: clang/include/clang/Basic/DiagnosticDriverKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -215,6 +215,8 @@
   "malformed sanitizer coverage allowlist: '%0'">;
 def err_drv_malformed_sanitizer_coverage_ignorelist : Error<
   "malformed sanitizer coverage ignorelist: '%0'">;
+def err_drv_malformed_sanitizer_metadata_ignorelist : Error<
+  "malformed sanitizer metadata ignorelist: '%0'">;
 def err_drv_unsupported_static_ubsan_darwin : Error<
   "static UndefinedBehaviorSanitizer runtime is not supported on darwin">;
 def err_drv_duplicate_config : Error<
Index: clang/include/clang/Basic/CodeGenOptions.h
===================================================================
--- clang/include/clang/Basic/CodeGenOptions.h
+++ clang/include/clang/Basic/CodeGenOptions.h
@@ -417,6 +417,11 @@
   /// coverage pass should actually not be instrumented.
   std::vector<std::string> SanitizeCoverageIgnorelistFiles;
 
+  /// Path to ignorelist file specifying which objects
+  /// (files, functions) listed for instrumentation by sanitizer
+  /// binary metadata pass should not be instrumented.
+  std::vector<std::string> SanitizeMetadataIgnorelistFiles;
+
   /// Name of the stack usage file (i.e., .su file) if user passes
   /// -fstack-usage. If empty, it can be implied that -fstack-usage is not
   /// passed on the command line.
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to