clang API Documentation

SanitizerMetadata.cpp
Go to the documentation of this file.
00001 //===--- SanitizerMetadata.cpp - Blacklist for sanitizers -----------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // Class which emits metadata consumed by sanitizer instrumentation passes.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 #include "SanitizerMetadata.h"
00014 #include "CodeGenModule.h"
00015 #include "clang/AST/Type.h"
00016 #include "llvm/ADT/StringRef.h"
00017 #include "llvm/IR/Constants.h"
00018 
00019 using namespace clang;
00020 using namespace CodeGen;
00021 
00022 SanitizerMetadata::SanitizerMetadata(CodeGenModule &CGM) : CGM(CGM) {}
00023 
00024 void SanitizerMetadata::reportGlobalToASan(llvm::GlobalVariable *GV,
00025                                            SourceLocation Loc, StringRef Name,
00026                                            QualType Ty, bool IsDynInit,
00027                                            bool IsBlacklisted) {
00028   if (!CGM.getLangOpts().Sanitize.has(SanitizerKind::Address))
00029     return;
00030   IsDynInit &= !CGM.isInSanitizerBlacklist(GV, Loc, Ty, "init");
00031   IsBlacklisted |= CGM.isInSanitizerBlacklist(GV, Loc, Ty);
00032 
00033   llvm::Value *LocDescr = nullptr;
00034   llvm::Value *GlobalName = nullptr;
00035   llvm::LLVMContext &VMContext = CGM.getLLVMContext();
00036   if (!IsBlacklisted) {
00037     // Don't generate source location and global name if it is blacklisted -
00038     // it won't be instrumented anyway.
00039     LocDescr = getLocationMetadata(Loc);
00040     if (!Name.empty())
00041       GlobalName = llvm::MDString::get(VMContext, Name);
00042   }
00043 
00044   llvm::Value *GlobalMetadata[] = {
00045       GV, LocDescr, GlobalName,
00046       llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), IsDynInit),
00047       llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), IsBlacklisted)};
00048 
00049   llvm::MDNode *ThisGlobal = llvm::MDNode::get(VMContext, GlobalMetadata);
00050   llvm::NamedMDNode *AsanGlobals =
00051       CGM.getModule().getOrInsertNamedMetadata("llvm.asan.globals");
00052   AsanGlobals->addOperand(ThisGlobal);
00053 }
00054 
00055 void SanitizerMetadata::reportGlobalToASan(llvm::GlobalVariable *GV,
00056                                            const VarDecl &D, bool IsDynInit) {
00057   if (!CGM.getLangOpts().Sanitize.has(SanitizerKind::Address))
00058     return;
00059   std::string QualName;
00060   llvm::raw_string_ostream OS(QualName);
00061   D.printQualifiedName(OS);
00062   reportGlobalToASan(GV, D.getLocation(), OS.str(), D.getType(), IsDynInit);
00063 }
00064 
00065 void SanitizerMetadata::disableSanitizerForGlobal(llvm::GlobalVariable *GV) {
00066   // For now, just make sure the global is not modified by the ASan
00067   // instrumentation.
00068   if (CGM.getLangOpts().Sanitize.has(SanitizerKind::Address))
00069     reportGlobalToASan(GV, SourceLocation(), "", QualType(), false, true);
00070 }
00071 
00072 void SanitizerMetadata::disableSanitizerForInstruction(llvm::Instruction *I) {
00073   I->setMetadata(
00074       CGM.getModule().getMDKindID("nosanitize"),
00075       llvm::MDNode::get(CGM.getLLVMContext(), ArrayRef<llvm::Value *>()));
00076 }
00077 
00078 llvm::MDNode *SanitizerMetadata::getLocationMetadata(SourceLocation Loc) {
00079   PresumedLoc PLoc = CGM.getContext().getSourceManager().getPresumedLoc(Loc);
00080   if (!PLoc.isValid())
00081     return nullptr;
00082   llvm::LLVMContext &VMContext = CGM.getLLVMContext();
00083   llvm::Value *LocMetadata[] = {
00084       llvm::MDString::get(VMContext, PLoc.getFilename()),
00085       llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), PLoc.getLine()),
00086       llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext),
00087                              PLoc.getColumn()),
00088   };
00089   return llvm::MDNode::get(VMContext, LocMetadata);
00090 }