clang  19.0.0git
SanitizerMetadata.cpp
Go to the documentation of this file.
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"
17 #include "llvm/ADT/StringRef.h"
18 #include "llvm/IR/Constants.h"
19 
20 using namespace clang;
21 using namespace CodeGen;
22 
23 SanitizerMetadata::SanitizerMetadata(CodeGenModule &CGM) : CGM(CGM) {}
24 
25 static bool isAsanHwasanOrMemTag(const SanitizerSet &SS) {
26  return SS.hasOneOf(SanitizerKind::Address | SanitizerKind::KernelAddress |
27  SanitizerKind::HWAddress | SanitizerKind::MemTag);
28 }
29 
31  if (Mask & (SanitizerKind::Address | SanitizerKind::KernelAddress))
32  Mask |= SanitizerKind::Address | SanitizerKind::KernelAddress;
33  // Note: KHWASan doesn't support globals.
34  return Mask;
35 }
36 
37 void SanitizerMetadata::reportGlobal(llvm::GlobalVariable *GV,
38  SourceLocation Loc, StringRef Name,
39  QualType Ty,
40  SanitizerMask NoSanitizeAttrMask,
41  bool IsDynInit) {
42  SanitizerSet FsanitizeArgument = CGM.getLangOpts().Sanitize;
43  if (!isAsanHwasanOrMemTag(FsanitizeArgument))
44  return;
45 
46  FsanitizeArgument.Mask = expandKernelSanitizerMasks(FsanitizeArgument.Mask);
47  NoSanitizeAttrMask = expandKernelSanitizerMasks(NoSanitizeAttrMask);
48  SanitizerSet NoSanitizeAttrSet = {NoSanitizeAttrMask &
49  FsanitizeArgument.Mask};
50 
51  llvm::GlobalVariable::SanitizerMetadata Meta;
52  if (GV->hasSanitizerMetadata())
53  Meta = GV->getSanitizerMetadata();
54 
55  Meta.NoAddress |= NoSanitizeAttrSet.hasOneOf(SanitizerKind::Address);
56  Meta.NoAddress |= CGM.isInNoSanitizeList(
57  FsanitizeArgument.Mask & SanitizerKind::Address, GV, Loc, Ty);
58 
59  Meta.NoHWAddress |= NoSanitizeAttrSet.hasOneOf(SanitizerKind::HWAddress);
60  Meta.NoHWAddress |= CGM.isInNoSanitizeList(
61  FsanitizeArgument.Mask & SanitizerKind::HWAddress, GV, Loc, Ty);
62 
63  Meta.Memtag |=
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);
68 
69  Meta.IsDynInit = IsDynInit && !Meta.NoAddress &&
70  FsanitizeArgument.has(SanitizerKind::Address) &&
71  !CGM.isInNoSanitizeList(SanitizerKind::Address |
72  SanitizerKind::KernelAddress,
73  GV, Loc, Ty, "init");
74 
75  GV->setSanitizerMetadata(Meta);
76 }
77 
78 void SanitizerMetadata::reportGlobal(llvm::GlobalVariable *GV, const VarDecl &D,
79  bool IsDynInit) {
81  return;
82  std::string QualName;
83  llvm::raw_string_ostream OS(QualName);
84  D.printQualifiedName(OS);
85 
86  auto getNoSanitizeMask = [](const VarDecl &D) {
87  if (D.hasAttr<DisableSanitizerInstrumentationAttr>())
88  return SanitizerKind::All;
89 
90  SanitizerMask NoSanitizeMask;
91  for (auto *Attr : D.specific_attrs<NoSanitizeAttr>())
92  NoSanitizeMask |= Attr->getMask();
93 
94  return NoSanitizeMask;
95  };
96 
97  reportGlobal(GV, D.getLocation(), OS.str(), D.getType(), getNoSanitizeMask(D),
98  IsDynInit);
99 }
100 
101 void SanitizerMetadata::disableSanitizerForGlobal(llvm::GlobalVariable *GV) {
103 }
SanitizerMask expandKernelSanitizerMasks(SanitizerMask Mask)
static bool isAsanHwasanOrMemTag(const SanitizerSet &SS)
SourceLocation Loc
Definition: SemaObjC.cpp:755
Defines the SourceManager interface.
C Language Family Type Representation.
Attr - This represents one attribute.
Definition: Attr.h:46
This class organizes the cross-function state that is used while generating LLVM code.
bool isInNoSanitizeList(SanitizerMask Kind, llvm::Function *Fn, SourceLocation Loc) const
const LangOptions & getLangOpts() const
void disableSanitizerForGlobal(llvm::GlobalVariable *GV)
void reportGlobal(llvm::GlobalVariable *GV, const VarDecl &D, bool IsDynInit=false)
SourceLocation getLocation() const
Definition: DeclBase.h:445
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const
Definition: DeclBase.h:565
bool hasAttr() const
Definition: DeclBase.h:583
SanitizerSet Sanitize
Set of enabled sanitizers.
Definition: LangOptions.h:488
void printQualifiedName(raw_ostream &OS) const
Returns a human-readable qualified name for this declaration, like A::B::i, for i being member of nam...
Definition: Decl.cpp:1691
A (possibly-)qualified type.
Definition: Type.h:940
Encodes a location in the source.
QualType getType() const
Definition: Decl.h:718
Represents a variable declaration or definition.
Definition: Decl.h:919
constexpr XRayInstrMask All
Definition: XRayInstr.h:43
The JSON file list parser is used to communicate input to InstallAPI.
bool has(SanitizerMask K) const
Check if a certain (single) sanitizer is enabled.
Definition: Sanitizers.h:159
SanitizerMask Mask
Bitmask of enabled sanitizers.
Definition: Sanitizers.h:182
bool hasOneOf(SanitizerMask K) const
Check if one or more sanitizers are enabled.
Definition: Sanitizers.h:165