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
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits