SanitizerMetadata.cpp 4.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. //===--- SanitizerMetadata.cpp - Blacklist for sanitizers -----------------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // Class which emits metadata consumed by sanitizer instrumentation passes.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #include "SanitizerMetadata.h"
  14. #include "CodeGenModule.h"
  15. #include "clang/AST/Type.h"
  16. #include "llvm/ADT/StringRef.h"
  17. #include "llvm/IR/Constants.h"
  18. // //
  19. ///////////////////////////////////////////////////////////////////////////////
  20. using namespace clang;
  21. using namespace CodeGen;
  22. SanitizerMetadata::SanitizerMetadata(CodeGenModule &CGM) : CGM(CGM) {}
  23. void SanitizerMetadata::reportGlobalToASan(llvm::GlobalVariable *GV,
  24. SourceLocation Loc, StringRef Name,
  25. QualType Ty, bool IsDynInit,
  26. bool IsBlacklisted) {
  27. if (!CGM.getLangOpts().Sanitize.hasOneOf(SanitizerKind::Address |
  28. SanitizerKind::KernelAddress))
  29. return;
  30. IsDynInit &= !CGM.isInSanitizerBlacklist(GV, Loc, Ty, "init");
  31. IsBlacklisted |= CGM.isInSanitizerBlacklist(GV, Loc, Ty);
  32. llvm::Metadata *LocDescr = nullptr;
  33. llvm::Metadata *GlobalName = nullptr;
  34. llvm::LLVMContext &VMContext = CGM.getLLVMContext();
  35. if (!IsBlacklisted) {
  36. // Don't generate source location and global name if it is blacklisted -
  37. // it won't be instrumented anyway.
  38. LocDescr = getLocationMetadata(Loc);
  39. if (!Name.empty())
  40. GlobalName = llvm::MDString::get(VMContext, Name);
  41. }
  42. llvm::Metadata *GlobalMetadata[] = {
  43. llvm::ConstantAsMetadata::get(GV), LocDescr, GlobalName,
  44. llvm::ConstantAsMetadata::get(
  45. llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), IsDynInit)),
  46. llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
  47. llvm::Type::getInt1Ty(VMContext), IsBlacklisted))};
  48. llvm::MDNode *ThisGlobal = llvm::MDNode::get(VMContext, GlobalMetadata);
  49. llvm::NamedMDNode *AsanGlobals =
  50. CGM.getModule().getOrInsertNamedMetadata("llvm.asan.globals");
  51. AsanGlobals->addOperand(ThisGlobal);
  52. }
  53. void SanitizerMetadata::reportGlobalToASan(llvm::GlobalVariable *GV,
  54. const VarDecl &D, bool IsDynInit) {
  55. if (!CGM.getLangOpts().Sanitize.hasOneOf(SanitizerKind::Address |
  56. SanitizerKind::KernelAddress))
  57. return;
  58. std::string QualName;
  59. llvm::raw_string_ostream OS(QualName);
  60. D.printQualifiedName(OS);
  61. reportGlobalToASan(GV, D.getLocation(), OS.str(), D.getType(), IsDynInit);
  62. }
  63. void SanitizerMetadata::disableSanitizerForGlobal(llvm::GlobalVariable *GV) {
  64. // For now, just make sure the global is not modified by the ASan
  65. // instrumentation.
  66. if (CGM.getLangOpts().Sanitize.hasOneOf(SanitizerKind::Address |
  67. SanitizerKind::KernelAddress))
  68. reportGlobalToASan(GV, SourceLocation(), "", QualType(), false, true);
  69. }
  70. void SanitizerMetadata::disableSanitizerForInstruction(llvm::Instruction *I) {
  71. I->setMetadata(CGM.getModule().getMDKindID("nosanitize"),
  72. llvm::MDNode::get(CGM.getLLVMContext(), None));
  73. }
  74. llvm::MDNode *SanitizerMetadata::getLocationMetadata(SourceLocation Loc) {
  75. PresumedLoc PLoc = CGM.getContext().getSourceManager().getPresumedLoc(Loc);
  76. if (!PLoc.isValid())
  77. return nullptr;
  78. llvm::LLVMContext &VMContext = CGM.getLLVMContext();
  79. llvm::Metadata *LocMetadata[] = {
  80. llvm::MDString::get(VMContext, PLoc.getFilename()),
  81. llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
  82. llvm::Type::getInt32Ty(VMContext), PLoc.getLine())),
  83. llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
  84. llvm::Type::getInt32Ty(VMContext), PLoc.getColumn())),
  85. };
  86. return llvm::MDNode::get(VMContext, LocMetadata);
  87. }