diff options
Diffstat (limited to 'clang/lib/CodeGen/SanitizerMetadata.cpp')
| -rw-r--r-- | clang/lib/CodeGen/SanitizerMetadata.cpp | 103 | 
1 files changed, 103 insertions, 0 deletions
| diff --git a/clang/lib/CodeGen/SanitizerMetadata.cpp b/clang/lib/CodeGen/SanitizerMetadata.cpp new file mode 100644 index 000000000000..ebc9cd5529bc --- /dev/null +++ b/clang/lib/CodeGen/SanitizerMetadata.cpp @@ -0,0 +1,103 @@ +//===--- SanitizerMetadata.cpp - Blacklist for sanitizers -----------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Class which emits metadata consumed by sanitizer instrumentation passes. +// +//===----------------------------------------------------------------------===// +#include "SanitizerMetadata.h" +#include "CodeGenModule.h" +#include "clang/AST/Type.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/IR/Constants.h" + +using namespace clang; +using namespace CodeGen; + +SanitizerMetadata::SanitizerMetadata(CodeGenModule &CGM) : CGM(CGM) {} + +static bool isAsanHwasanOrMemTag(const SanitizerSet& SS) { +  return SS.hasOneOf(SanitizerKind::Address | SanitizerKind::KernelAddress | +                     SanitizerKind::HWAddress | SanitizerKind::KernelHWAddress | +                     SanitizerKind::MemTag); +} + +void SanitizerMetadata::reportGlobalToASan(llvm::GlobalVariable *GV, +                                           SourceLocation Loc, StringRef Name, +                                           QualType Ty, bool IsDynInit, +                                           bool IsBlacklisted) { +  if (!isAsanHwasanOrMemTag(CGM.getLangOpts().Sanitize)) +    return; +  IsDynInit &= !CGM.isInSanitizerBlacklist(GV, Loc, Ty, "init"); +  IsBlacklisted |= CGM.isInSanitizerBlacklist(GV, Loc, Ty); + +  llvm::Metadata *LocDescr = nullptr; +  llvm::Metadata *GlobalName = nullptr; +  llvm::LLVMContext &VMContext = CGM.getLLVMContext(); +  if (!IsBlacklisted) { +    // Don't generate source location and global name if it is blacklisted - +    // it won't be instrumented anyway. +    LocDescr = getLocationMetadata(Loc); +    if (!Name.empty()) +      GlobalName = llvm::MDString::get(VMContext, Name); +  } + +  llvm::Metadata *GlobalMetadata[] = { +      llvm::ConstantAsMetadata::get(GV), LocDescr, GlobalName, +      llvm::ConstantAsMetadata::get( +          llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), IsDynInit)), +      llvm::ConstantAsMetadata::get(llvm::ConstantInt::get( +          llvm::Type::getInt1Ty(VMContext), IsBlacklisted))}; + +  llvm::MDNode *ThisGlobal = llvm::MDNode::get(VMContext, GlobalMetadata); +  llvm::NamedMDNode *AsanGlobals = +      CGM.getModule().getOrInsertNamedMetadata("llvm.asan.globals"); +  AsanGlobals->addOperand(ThisGlobal); +} + +void SanitizerMetadata::reportGlobalToASan(llvm::GlobalVariable *GV, +                                           const VarDecl &D, bool IsDynInit) { +  if (!isAsanHwasanOrMemTag(CGM.getLangOpts().Sanitize)) +    return; +  std::string QualName; +  llvm::raw_string_ostream OS(QualName); +  D.printQualifiedName(OS); + +  bool IsBlacklisted = false; +  for (auto Attr : D.specific_attrs<NoSanitizeAttr>()) +    if (Attr->getMask() & SanitizerKind::Address) +      IsBlacklisted = true; +  reportGlobalToASan(GV, D.getLocation(), OS.str(), D.getType(), IsDynInit, +                     IsBlacklisted); +} + +void SanitizerMetadata::disableSanitizerForGlobal(llvm::GlobalVariable *GV) { +  // For now, just make sure the global is not modified by the ASan +  // instrumentation. +  if (isAsanHwasanOrMemTag(CGM.getLangOpts().Sanitize)) +    reportGlobalToASan(GV, SourceLocation(), "", QualType(), false, true); +} + +void SanitizerMetadata::disableSanitizerForInstruction(llvm::Instruction *I) { +  I->setMetadata(CGM.getModule().getMDKindID("nosanitize"), +                 llvm::MDNode::get(CGM.getLLVMContext(), None)); +} + +llvm::MDNode *SanitizerMetadata::getLocationMetadata(SourceLocation Loc) { +  PresumedLoc PLoc = CGM.getContext().getSourceManager().getPresumedLoc(Loc); +  if (!PLoc.isValid()) +    return nullptr; +  llvm::LLVMContext &VMContext = CGM.getLLVMContext(); +  llvm::Metadata *LocMetadata[] = { +      llvm::MDString::get(VMContext, PLoc.getFilename()), +      llvm::ConstantAsMetadata::get(llvm::ConstantInt::get( +          llvm::Type::getInt32Ty(VMContext), PLoc.getLine())), +      llvm::ConstantAsMetadata::get(llvm::ConstantInt::get( +          llvm::Type::getInt32Ty(VMContext), PLoc.getColumn())), +  }; +  return llvm::MDNode::get(VMContext, LocMetadata); +} | 
