1 //===--- SanitizerMetadata.cpp - Ignored entities for sanitizers ----------===//
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
7 //===----------------------------------------------------------------------===//
9 // Class which emits metadata consumed by sanitizer instrumentation passes.
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"
20 using namespace clang
;
21 using namespace CodeGen
;
23 SanitizerMetadata::SanitizerMetadata(CodeGenModule
&CGM
) : CGM(CGM
) {}
25 static bool isAsanHwasanOrMemTag(const SanitizerSet
&SS
) {
26 return SS
.hasOneOf(SanitizerKind::Address
| SanitizerKind::KernelAddress
|
27 SanitizerKind::HWAddress
| SanitizerKind::MemTag
);
30 SanitizerMask
expandKernelSanitizerMasks(SanitizerMask Mask
) {
31 if (Mask
& (SanitizerKind::Address
| SanitizerKind::KernelAddress
))
32 Mask
|= SanitizerKind::Address
| SanitizerKind::KernelAddress
;
33 // Note: KHWASan doesn't support globals.
37 void SanitizerMetadata::reportGlobal(llvm::GlobalVariable
*GV
,
38 SourceLocation Loc
, StringRef Name
,
40 SanitizerMask NoSanitizeAttrMask
,
42 SanitizerSet FsanitizeArgument
= CGM
.getLangOpts().Sanitize
;
43 if (!isAsanHwasanOrMemTag(FsanitizeArgument
))
46 FsanitizeArgument
.Mask
= expandKernelSanitizerMasks(FsanitizeArgument
.Mask
);
47 NoSanitizeAttrMask
= expandKernelSanitizerMasks(NoSanitizeAttrMask
);
48 SanitizerSet NoSanitizeAttrSet
= {NoSanitizeAttrMask
&
49 FsanitizeArgument
.Mask
};
51 llvm::GlobalVariable::SanitizerMetadata Meta
;
52 if (GV
->hasSanitizerMetadata())
53 Meta
= GV
->getSanitizerMetadata();
55 Meta
.NoAddress
|= NoSanitizeAttrSet
.hasOneOf(SanitizerKind::Address
);
56 Meta
.NoAddress
|= CGM
.isInNoSanitizeList(
57 FsanitizeArgument
.Mask
& SanitizerKind::Address
, GV
, Loc
, Ty
);
59 Meta
.NoHWAddress
|= NoSanitizeAttrSet
.hasOneOf(SanitizerKind::HWAddress
);
60 Meta
.NoHWAddress
|= CGM
.isInNoSanitizeList(
61 FsanitizeArgument
.Mask
& SanitizerKind::HWAddress
, GV
, Loc
, Ty
);
64 static_cast<bool>(FsanitizeArgument
.Mask
& SanitizerKind::MemtagGlobals
);
65 Meta
.Memtag
&= !NoSanitizeAttrSet
.hasOneOf(SanitizerKind::MemTag
);
66 Meta
.Memtag
&= !CGM
.isInNoSanitizeList(
67 FsanitizeArgument
.Mask
& SanitizerKind::MemTag
, GV
, Loc
, Ty
);
69 Meta
.IsDynInit
= IsDynInit
&& !Meta
.NoAddress
&&
70 FsanitizeArgument
.has(SanitizerKind::Address
) &&
71 !CGM
.isInNoSanitizeList(SanitizerKind::Address
|
72 SanitizerKind::KernelAddress
,
75 GV
->setSanitizerMetadata(Meta
);
78 void SanitizerMetadata::reportGlobal(llvm::GlobalVariable
*GV
, const VarDecl
&D
,
80 if (!isAsanHwasanOrMemTag(CGM
.getLangOpts().Sanitize
))
83 llvm::raw_string_ostream
OS(QualName
);
84 D
.printQualifiedName(OS
);
86 auto getNoSanitizeMask
= [](const VarDecl
&D
) {
87 if (D
.hasAttr
<DisableSanitizerInstrumentationAttr
>())
88 return SanitizerKind::All
;
90 SanitizerMask NoSanitizeMask
;
91 for (auto *Attr
: D
.specific_attrs
<NoSanitizeAttr
>())
92 NoSanitizeMask
|= Attr
->getMask();
94 return NoSanitizeMask
;
97 reportGlobal(GV
, D
.getLocation(), OS
.str(), D
.getType(), getNoSanitizeMask(D
),
101 void SanitizerMetadata::disableSanitizerForGlobal(llvm::GlobalVariable
*GV
) {
102 reportGlobal(GV
, SourceLocation(), "", QualType(), SanitizerKind::All
);