Coverage Report

Created: 2022-07-16 07:03

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/CodeGen/SanitizerMetadata.cpp
Line
Count
Source
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
36.4k
SanitizerMetadata::SanitizerMetadata(CodeGenModule &CGM) : CGM(CGM) {}
24
25
132k
static bool isAsanHwasanOrMemTag(const SanitizerSet &SS) {
26
132k
  return SS.hasOneOf(SanitizerKind::Address | SanitizerKind::KernelAddress |
27
132k
                     SanitizerKind::HWAddress | SanitizerKind::MemTag);
28
132k
}
29
30
1.08k
SanitizerMask expandKernelSanitizerMasks(SanitizerMask Mask) {
31
1.08k
  if (Mask & (SanitizerKind::Address | SanitizerKind::KernelAddress))
32
517
    Mask |= SanitizerKind::Address | SanitizerKind::KernelAddress;
33
  // Note: KHWASan doesn't support globals.
34
1.08k
  return Mask;
35
1.08k
}
36
37
void SanitizerMetadata::reportGlobal(llvm::GlobalVariable *GV,
38
                                     SourceLocation Loc, StringRef Name,
39
                                     QualType Ty,
40
                                     SanitizerMask NoSanitizeAttrMask,
41
61.2k
                                     bool IsDynInit) {
42
61.2k
  SanitizerSet FsanitizeArgument = CGM.getLangOpts().Sanitize;
43
61.2k
  if (!isAsanHwasanOrMemTag(FsanitizeArgument))
44
60.7k
    return;
45
46
544
  FsanitizeArgument.Mask = expandKernelSanitizerMasks(FsanitizeArgument.Mask);
47
544
  NoSanitizeAttrMask = expandKernelSanitizerMasks(NoSanitizeAttrMask);
48
544
  SanitizerSet NoSanitizeAttrSet = {NoSanitizeAttrMask &
49
544
                                    FsanitizeArgument.Mask};
50
51
544
  llvm::GlobalVariable::SanitizerMetadata Meta;
52
544
  if (GV->hasSanitizerMetadata())
53
249
    Meta = GV->getSanitizerMetadata();
54
55
544
  Meta.NoAddress |= NoSanitizeAttrSet.hasOneOf(SanitizerKind::Address);
56
544
  Meta.NoAddress |= CGM.isInNoSanitizeList(
57
544
      FsanitizeArgument.Mask & SanitizerKind::Address, GV, Loc, Ty);
58
59
544
  Meta.NoHWAddress |= NoSanitizeAttrSet.hasOneOf(SanitizerKind::HWAddress);
60
544
  Meta.NoHWAddress |= CGM.isInNoSanitizeList(
61
544
      FsanitizeArgument.Mask & SanitizerKind::HWAddress, GV, Loc, Ty);
62
63
544
  Meta.Memtag |=
64
544
      static_cast<bool>(FsanitizeArgument.Mask & SanitizerKind::MemtagGlobals);
65
544
  Meta.Memtag &= !NoSanitizeAttrSet.hasOneOf(SanitizerKind::MemTag);
66
544
  Meta.Memtag &= !CGM.isInNoSanitizeList(
67
544
      FsanitizeArgument.Mask & SanitizerKind::MemTag, GV, Loc, Ty);
68
69
544
  Meta.IsDynInit = IsDynInit && 
!Meta.NoAddress75
&&
70
544
                   
FsanitizeArgument.has(SanitizerKind::Address)71
&&
71
544
                   !CGM.isInNoSanitizeList(SanitizerKind::Address |
72
71
                                               SanitizerKind::KernelAddress,
73
71
                                           GV, Loc, Ty, "init");
74
75
544
  GV->setSanitizerMetadata(Meta);
76
544
}
77
78
void SanitizerMetadata::reportGlobal(llvm::GlobalVariable *GV, const VarDecl &D,
79
70.8k
                                     bool IsDynInit) {
80
70.8k
  if (!isAsanHwasanOrMemTag(CGM.getLangOpts().Sanitize))
81
70.3k
    return;
82
499
  std::string QualName;
83
499
  llvm::raw_string_ostream OS(QualName);
84
499
  D.printQualifiedName(OS);
85
86
499
  auto getNoSanitizeMask = [](const VarDecl &D) {
87
499
    if (D.hasAttr<DisableSanitizerInstrumentationAttr>())
88
18
      return SanitizerKind::All;
89
90
481
    SanitizerMask NoSanitizeMask;
91
481
    for (auto *Attr : D.specific_attrs<NoSanitizeAttr>())
92
25
      NoSanitizeMask |= Attr->getMask();
93
94
481
    return NoSanitizeMask;
95
499
  };
96
97
499
  reportGlobal(GV, D.getLocation(), OS.str(), D.getType(), getNoSanitizeMask(D),
98
499
               IsDynInit);
99
499
}
100
101
4.06k
void SanitizerMetadata::disableSanitizerForGlobal(llvm::GlobalVariable *GV) {
102
4.06k
  reportGlobal(GV, SourceLocation(), "", QualType(), SanitizerKind::All);
103
4.06k
}
104
105
15.6k
void SanitizerMetadata::disableSanitizerForInstruction(llvm::Instruction *I) {
106
15.6k
  I->setMetadata(llvm::LLVMContext::MD_nosanitize,
107
15.6k
                 llvm::MDNode::get(CGM.getLLVMContext(), None));
108
15.6k
}