/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/CodeGen/SanitizerMetadata.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===--- SanitizerMetadata.cpp - Ignored entities for sanitizers ----------===// |
2 | | // |
3 | | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | | // See https://llvm.org/LICENSE.txt for license information. |
5 | | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | | // |
7 | | //===----------------------------------------------------------------------===// |
8 | | // |
9 | | // Class which emits metadata consumed by sanitizer instrumentation passes. |
10 | | // |
11 | | //===----------------------------------------------------------------------===// |
12 | | #include "SanitizerMetadata.h" |
13 | | #include "CodeGenModule.h" |
14 | | #include "clang/AST/Attr.h" |
15 | | #include "clang/AST/Type.h" |
16 | | #include "clang/Basic/SourceManager.h" |
17 | | #include "llvm/ADT/StringRef.h" |
18 | | #include "llvm/IR/Constants.h" |
19 | | |
20 | | using namespace clang; |
21 | | using namespace CodeGen; |
22 | | |
23 | 35.6k | SanitizerMetadata::SanitizerMetadata(CodeGenModule &CGM) : CGM(CGM) {} |
24 | | |
25 | 95.7k | static bool isAsanHwasanOrMemTag(const SanitizerSet& SS) { |
26 | 95.7k | return SS.hasOneOf(SanitizerKind::Address | SanitizerKind::KernelAddress | |
27 | 95.7k | SanitizerKind::HWAddress | SanitizerKind::KernelHWAddress | |
28 | 95.7k | SanitizerKind::MemTag); |
29 | 95.7k | } |
30 | | |
31 | | void SanitizerMetadata::reportGlobalToASan(llvm::GlobalVariable *GV, |
32 | | SourceLocation Loc, StringRef Name, |
33 | | QualType Ty, bool IsDynInit, |
34 | 56.0k | bool IsExcluded) { |
35 | 56.0k | if (!isAsanHwasanOrMemTag(CGM.getLangOpts().Sanitize)) |
36 | 55.8k | return; |
37 | 232 | IsDynInit &= !CGM.isInNoSanitizeList(GV, Loc, Ty, "init"); |
38 | 232 | IsExcluded |= CGM.isInNoSanitizeList(GV, Loc, Ty); |
39 | | |
40 | 232 | llvm::Metadata *LocDescr = nullptr; |
41 | 232 | llvm::Metadata *GlobalName = nullptr; |
42 | 232 | llvm::LLVMContext &VMContext = CGM.getLLVMContext(); |
43 | 232 | if (!IsExcluded) { |
44 | | // Don't generate source location and global name if it is on |
45 | | // the NoSanitizeList - it won't be instrumented anyway. |
46 | 174 | LocDescr = getLocationMetadata(Loc); |
47 | 174 | if (!Name.empty()) |
48 | 174 | GlobalName = llvm::MDString::get(VMContext, Name); |
49 | 174 | } |
50 | | |
51 | 232 | llvm::Metadata *GlobalMetadata[] = { |
52 | 232 | llvm::ConstantAsMetadata::get(GV), LocDescr, GlobalName, |
53 | 232 | llvm::ConstantAsMetadata::get( |
54 | 232 | llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), IsDynInit)), |
55 | 232 | llvm::ConstantAsMetadata::get(llvm::ConstantInt::get( |
56 | 232 | llvm::Type::getInt1Ty(VMContext), IsExcluded))}; |
57 | | |
58 | 232 | llvm::MDNode *ThisGlobal = llvm::MDNode::get(VMContext, GlobalMetadata); |
59 | 232 | llvm::NamedMDNode *AsanGlobals = |
60 | 232 | CGM.getModule().getOrInsertNamedMetadata("llvm.asan.globals"); |
61 | 232 | AsanGlobals->addOperand(ThisGlobal); |
62 | 232 | } |
63 | | |
64 | | void SanitizerMetadata::reportGlobalToASan(llvm::GlobalVariable *GV, |
65 | 35.6k | const VarDecl &D, bool IsDynInit) { |
66 | 35.6k | if (!isAsanHwasanOrMemTag(CGM.getLangOpts().Sanitize)) |
67 | 35.4k | return; |
68 | 194 | std::string QualName; |
69 | 194 | llvm::raw_string_ostream OS(QualName); |
70 | 194 | D.printQualifiedName(OS); |
71 | | |
72 | 194 | bool IsExcluded = false; |
73 | 194 | for (auto Attr : D.specific_attrs<NoSanitizeAttr>()) |
74 | 5 | if (Attr->getMask() & SanitizerKind::Address) |
75 | 5 | IsExcluded = true; |
76 | 194 | if (D.hasAttr<DisableSanitizerInstrumentationAttr>()) |
77 | 5 | IsExcluded = true; |
78 | 194 | reportGlobalToASan(GV, D.getLocation(), OS.str(), D.getType(), IsDynInit, |
79 | 194 | IsExcluded); |
80 | 194 | } |
81 | | |
82 | 4.04k | void SanitizerMetadata::disableSanitizerForGlobal(llvm::GlobalVariable *GV) { |
83 | | // For now, just make sure the global is not modified by the ASan |
84 | | // instrumentation. |
85 | 4.04k | if (isAsanHwasanOrMemTag(CGM.getLangOpts().Sanitize)) |
86 | 29 | reportGlobalToASan(GV, SourceLocation(), "", QualType(), false, true); |
87 | 4.04k | } |
88 | | |
89 | 15.5k | void SanitizerMetadata::disableSanitizerForInstruction(llvm::Instruction *I) { |
90 | 15.5k | I->setMetadata(CGM.getModule().getMDKindID("nosanitize"), |
91 | 15.5k | llvm::MDNode::get(CGM.getLLVMContext(), None)); |
92 | 15.5k | } |
93 | | |
94 | 174 | llvm::MDNode *SanitizerMetadata::getLocationMetadata(SourceLocation Loc) { |
95 | 174 | PresumedLoc PLoc = CGM.getContext().getSourceManager().getPresumedLoc(Loc); |
96 | 174 | if (!PLoc.isValid()) |
97 | 0 | return nullptr; |
98 | 174 | llvm::LLVMContext &VMContext = CGM.getLLVMContext(); |
99 | 174 | llvm::Metadata *LocMetadata[] = { |
100 | 174 | llvm::MDString::get(VMContext, PLoc.getFilename()), |
101 | 174 | llvm::ConstantAsMetadata::get(llvm::ConstantInt::get( |
102 | 174 | llvm::Type::getInt32Ty(VMContext), PLoc.getLine())), |
103 | 174 | llvm::ConstantAsMetadata::get(llvm::ConstantInt::get( |
104 | 174 | llvm::Type::getInt32Ty(VMContext), PLoc.getColumn())), |
105 | 174 | }; |
106 | 174 | return llvm::MDNode::get(VMContext, LocMetadata); |
107 | 174 | } |