clang API Documentation
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 }