leonardchan updated this revision to Diff 251421.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D76416

Files:
  clang/include/clang/Basic/CodeGenOptions.h
  clang/lib/CodeGen/ModuleBuilder.cpp
  clang/lib/CodeGen/SanitizerMetadata.cpp
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/test/CodeGen/asan-globals-file-prefix-map.cpp
  llvm/include/llvm/Transforms/Instrumentation/AddressSanitizer.h
  llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
  llvm/test/Instrumentation/AddressSanitizer/asan_file_prefix_map.ll
  llvm/test/Instrumentation/AddressSanitizer/asan_no_file_prefix_map.ll

Index: llvm/test/Instrumentation/AddressSanitizer/asan_no_file_prefix_map.ll
===================================================================
--- /dev/null
+++ llvm/test/Instrumentation/AddressSanitizer/asan_no_file_prefix_map.ll
@@ -0,0 +1,20 @@
+; RUN: opt < %s -asan -asan-module -S | FileCheck %s
+
+target triple = "x86_64-unknown-linux-gnu"
+
+@global = global i32 0, align 4
+@global2 = global i32 0, align 4
+
+; Check that the string used for the source location has its original prefix.
+; CHECK: @___asan_gen_.{{[0-9]+}} = private unnamed_addr constant [22 x i8] c"/tmp/asan-globals.cpp\00", align 1
+; CHECK: @___asan_gen_.{{[0-9]+}} = private unnamed_addr constant [22 x i8] c"blah/asan-globals.cpp\00", align 1
+
+!llvm.asan.globals = !{!0, !1}
+!101 = !{!"/tmp", !"/some/other/tmp"}
+!102 = !{!"blah", !"../some/other/blah"}
+
+!0 = !{i32* @global, !6, !"global", i1 false, i1 false}
+!1 = !{i32* @global2, !7, !"global2", i1 false, i1 false}
+
+!6 = !{!"/tmp/asan-globals.cpp", i32 5, i32 5}
+!7 = !{!"blah/asan-globals.cpp", i32 5, i32 5}
Index: llvm/test/Instrumentation/AddressSanitizer/asan_file_prefix_map.ll
===================================================================
--- /dev/null
+++ llvm/test/Instrumentation/AddressSanitizer/asan_file_prefix_map.ll
@@ -0,0 +1,21 @@
+; RUN: opt < %s -asan -asan-module -S | FileCheck %s
+
+target triple = "x86_64-unknown-linux-gnu"
+
+@global = global i32 0, align 4
+@global2 = global i32 0, align 4
+
+; Check that the string used for the source location has it's prefix replaced if llvm.asan.file.prefix.map is present.
+; CHECK: @___asan_gen_.{{[0-9]+}} = private unnamed_addr constant [33 x i8] c"/some/other/tmp/asan-globals.cpp\00", align 1
+; CHECK: @___asan_gen_.{{[0-9]+}} = private unnamed_addr constant [36 x i8] c"../some/other/blah/asan-globals.cpp\00", align 1
+
+!llvm.asan.globals = !{!0, !1}
+!llvm.asan.file.prefix.map = !{!101, !102}
+!101 = !{!"/tmp", !"/some/other/tmp"}
+!102 = !{!"blah", !"../some/other/blah"}
+
+!0 = !{i32* @global, !6, !"global", i1 false, i1 false}
+!1 = !{i32* @global2, !7, !"global2", i1 false, i1 false}
+
+!6 = !{!"/tmp/asan-globals.cpp", i32 5, i32 5}
+!7 = !{!"blah/asan-globals.cpp", i32 5, i32 5}
Index: llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
===================================================================
--- llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
+++ llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
@@ -1151,6 +1151,26 @@
         mdconst::extract<ConstantInt>(MDN->getOperand(4));
     E.IsBlacklisted |= IsBlacklisted->isOne();
   }
+
+  // Go through the file prefix map to replace prefixes in metadata that may
+  // contain filepaths. Do this once in the globals metadata pass so we don't
+  // need to run over the map in ASan for each metadata instance.
+  NamedMDNode *PrefixMap = M.getNamedMetadata("llvm.asan.file.prefix.map");
+  if (!PrefixMap)
+    return;
+  for (auto &Entry : Entries) {
+    for (auto *MDN : PrefixMap->operands()) {
+      assert(MDN->getNumOperands() == 2 &&
+             "Each node in the prefix map should be a pair");
+      StringRef Prefix = cast<MDString>(MDN->getOperand(0))->getString();
+      StringRef Replacement = cast<MDString>(MDN->getOperand(1))->getString();
+      if (llvm::sys::path::replace_path_prefix(
+              Entry.second.SourceLoc.Filename, Prefix, Replacement,
+              llvm::sys::path::Style::native, true)) {
+        break;
+      }
+    }
+  }
 }
 
 AnalysisKey ASanGlobalsMetadataAnalysis::Key;
Index: llvm/include/llvm/Transforms/Instrumentation/AddressSanitizer.h
===================================================================
--- llvm/include/llvm/Transforms/Instrumentation/AddressSanitizer.h
+++ llvm/include/llvm/Transforms/Instrumentation/AddressSanitizer.h
@@ -22,7 +22,7 @@
 
 /// Frontend-provided metadata for source location.
 struct LocationMetadata {
-  StringRef Filename;
+  llvm::SmallString<64> Filename;
   int LineNo = 0;
   int ColumnNo = 0;
 
Index: clang/test/CodeGen/asan-globals-file-prefix-map.cpp
===================================================================
--- /dev/null
+++ clang/test/CodeGen/asan-globals-file-prefix-map.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 %s -fsanitize=address -ffile-prefix-map=%S=/tmp -S -emit-llvm -o - %s -triple x86_64-unknown-linux-gnu| FileCheck %s
+
+int global;
+
+// Check that the __asan_gen_* contants use the prefix map.
+// CHECK: @global = global { i32, [60 x i8] } zeroinitializer, align 32
+// CHECK: @___asan_gen_{{\.?[0-9]*}} = private constant [38 x i8] c"/tmp/asan-globals-file-prefix-map.cpp\00", align 1
+// CHECK: @___asan_gen_{{\.?[0-9]*}} = private unnamed_addr constant [38 x i8] c"/tmp/asan-globals-file-prefix-map.cpp\00", align 1
+
+// Check that the `llvm.asan.file.prefix.map` metadata is emitted.
+// CHECK: !llvm.asan.globals = !{[[GLOBAL:\![0-9]+]]}
+// CHECK: !llvm.asan.file.prefix.map = !{[[MAPPING:\![0-9]+]]}
+
+// CHECK: [[GLOBAL]] = !{i32* getelementptr{{.*}} [[MDLOC:![0-9]+]], !"global"
+// CHECK: [[MDLOC]] = !{!"[[PATH:.+]]/asan-globals-file-prefix-map.cpp"
+// CHECK: [[MAPPING]] = !{!"[[PATH]]", !"/tmp"}
Index: clang/lib/Frontend/CompilerInvocation.cpp
===================================================================
--- clang/lib/Frontend/CompilerInvocation.cpp
+++ clang/lib/Frontend/CompilerInvocation.cpp
@@ -775,6 +775,12 @@
         {std::string(Split.first), std::string(Split.second)});
   }
 
+  for (const auto &Arg : Args.getAllArgValues(OPT_ffile_prefix_map_EQ)) {
+    auto Split = StringRef(Arg).split('=');
+    Opts.FilePrefixMap.insert(
+        {std::string(Split.first), std::string(Split.second)});
+  }
+
   if (const Arg *A =
           Args.getLastArg(OPT_emit_llvm_uselists, OPT_no_emit_llvm_uselists))
     Opts.EmitLLVMUseLists = A->getOption().getID() == OPT_emit_llvm_uselists;
Index: clang/lib/Driver/ToolChains/Clang.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Clang.cpp
+++ clang/lib/Driver/ToolChains/Clang.cpp
@@ -661,6 +661,20 @@
   }
 }
 
+/// Add a CC1 option to specify the file path prefix map.
+static void addFilePrefixMapArgMapArg(const Driver &D, const ArgList &Args,
+                                      ArgStringList &CmdArgs) {
+  for (const Arg *A : Args.filtered(options::OPT_ffile_prefix_map_EQ)) {
+    StringRef Map = A->getValue();
+    if (Map.find('=') == StringRef::npos)
+      D.Diag(diag::err_drv_invalid_argument_to_option)
+          << Map << A->getOption().getName();
+    else
+      CmdArgs.push_back(Args.MakeArgString("-ffile-prefix-map=" + Map));
+    A->claim();
+  }
+}
+
 /// Vectorize at all optimization levels greater than 1 except for -Oz.
 /// For -Oz the loop vectorizer is disabled, while the slp vectorizer is
 /// enabled.
@@ -4994,6 +5008,7 @@
   addDebugCompDirArg(Args, CmdArgs, D.getVFS());
 
   addDebugPrefixMapArg(D, Args, CmdArgs);
+  addFilePrefixMapArgMapArg(D, Args, CmdArgs);
 
   if (Arg *A = Args.getLastArg(options::OPT_ftemplate_depth_,
                                options::OPT_ftemplate_depth_EQ)) {
Index: clang/lib/CodeGen/SanitizerMetadata.cpp
===================================================================
--- clang/lib/CodeGen/SanitizerMetadata.cpp
+++ clang/lib/CodeGen/SanitizerMetadata.cpp
@@ -20,6 +20,9 @@
 using namespace clang;
 using namespace CodeGen;
 
+static constexpr char kASanFilePrefixMapMetadata[] =
+    "llvm.asan.file.prefix.map";
+
 SanitizerMetadata::SanitizerMetadata(CodeGenModule &CGM) : CGM(CGM) {}
 
 static bool isAsanHwasanOrMemTag(const SanitizerSet& SS) {
@@ -59,6 +62,30 @@
   llvm::NamedMDNode *AsanGlobals =
       CGM.getModule().getOrInsertNamedMetadata("llvm.asan.globals");
   AsanGlobals->addOperand(ThisGlobal);
+
+  // Add metadata to propgate file prefix mappings down to ASan. We can't edit
+  // the existing metadata passed to llvm.asan.globals because the metadata
+  // contains StringRefs that we can't edit. These refs point to strings all the
+  // way back to strings from the SourceManager.
+  //
+  // This will be an array of key-value pairs from the prefix mapping stored in
+  // the codegen options. These can be used to adjust the paths used during the
+  // ASanGlobalsMetadata analysis.
+
+  // Make sure not to add the prefix metadata more than once.
+  if (CGM.getModule().getNamedMetadata(kASanFilePrefixMapMetadata))
+    return;
+
+  llvm::NamedMDNode *AsanPrefixMapGlobals =
+      CGM.getModule().getOrInsertNamedMetadata(kASanFilePrefixMapMetadata);
+  for (const auto &Entry : CGM.getCodeGenOpts().FilePrefixMap) {
+    llvm::Metadata *PrefixPairMetadata[] = {
+        llvm::MDString::get(VMContext, Entry.getKey()),
+        llvm::MDString::get(VMContext, Entry.getValue()),
+    };
+    AsanPrefixMapGlobals->addOperand(
+        llvm::MDNode::get(VMContext, PrefixPairMetadata));
+  }
 }
 
 void SanitizerMetadata::reportGlobalToASan(llvm::GlobalVariable *GV,
Index: clang/lib/CodeGen/ModuleBuilder.cpp
===================================================================
--- clang/lib/CodeGen/ModuleBuilder.cpp
+++ clang/lib/CodeGen/ModuleBuilder.cpp
@@ -65,11 +65,18 @@
   private:
     SmallVector<FunctionDecl *, 8> DeferredInlineMemberFuncDefs;
 
-    static llvm::StringRef ExpandModuleName(llvm::StringRef ModuleName,
-                                            const CodeGenOptions &CGO) {
-      if (ModuleName == "-" && !CGO.MainFileName.empty())
-        return CGO.MainFileName;
-      return ModuleName;
+    static llvm::SmallString<64> ExpandModuleName(llvm::StringRef ModuleName,
+                                                  const CodeGenOptions &CGO) {
+      llvm::SmallString<64> Name =
+          (ModuleName == "-" && !CGO.MainFileName.empty()) ? CGO.MainFileName
+                                                           : ModuleName;
+      for (const auto &Entry : CGO.FilePrefixMap) {
+        if (llvm::sys::path::replace_path_prefix(
+                Name, Entry.getKey(), Entry.getValue(),
+                llvm::sys::path::Style::native, true))
+          break;
+      }
+      return Name;
     }
 
   public:
@@ -80,8 +87,9 @@
                       CoverageSourceInfo *CoverageInfo = nullptr)
         : Diags(diags), Ctx(nullptr), HeaderSearchOpts(HSO),
           PreprocessorOpts(PPO), CodeGenOpts(CGO), HandlingTopLevelDecls(0),
-          CoverageInfo(CoverageInfo),
-          M(new llvm::Module(ExpandModuleName(ModuleName, CGO), C)) {
+          CoverageInfo(CoverageInfo) {
+      auto ExpandedName = ExpandModuleName(ModuleName, CGO);
+      M.reset(new llvm::Module(ExpandedName, C));
       C.setDiscardValueNames(CGO.DiscardValueNames);
     }
 
@@ -129,7 +137,8 @@
     llvm::Module *StartModule(llvm::StringRef ModuleName,
                               llvm::LLVMContext &C) {
       assert(!M && "Replacing existing Module?");
-      M.reset(new llvm::Module(ExpandModuleName(ModuleName, CodeGenOpts), C));
+      auto ExpandedName = ExpandModuleName(ModuleName, CodeGenOpts);
+      M.reset(new llvm::Module(ExpandedName, C));
       Initialize(*Ctx);
       return M.get();
     }
Index: clang/include/clang/Basic/CodeGenOptions.h
===================================================================
--- clang/include/clang/Basic/CodeGenOptions.h
+++ clang/include/clang/Basic/CodeGenOptions.h
@@ -17,6 +17,7 @@
 #include "clang/Basic/Sanitizers.h"
 #include "clang/Basic/XRayInstr.h"
 #include "llvm/ADT/FloatingPointMode.h"
+#include "llvm/ADT/StringMap.h"
 #include "llvm/Support/CodeGen.h"
 #include "llvm/Support/Regex.h"
 #include "llvm/Target/TargetOptions.h"
@@ -160,6 +161,9 @@
 
   std::map<std::string, std::string> DebugPrefixMap;
 
+  /// Prefix mapping for file prefixes.
+  llvm::StringMap<std::string> FilePrefixMap;
+
   /// The ABI to use for passing floating point arguments.
   std::string FloatABI;
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to