diff options
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r-- | clang/lib/CodeGen/CGClass.cpp | 9 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGVTables.cpp | 57 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 4 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.h | 12 | ||||
-rw-r--r-- | clang/lib/CodeGen/MicrosoftCXXABI.cpp | 17 |
5 files changed, 49 insertions, 50 deletions
diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp index 71b305c773d..351dae9d4dd 100644 --- a/clang/lib/CodeGen/CGClass.cpp +++ b/clang/lib/CodeGen/CGClass.cpp @@ -2489,7 +2489,7 @@ void CodeGenFunction::EmitBitSetCodeForVCall(const CXXRecordDecl *RD, llvm::Value *VTable, SourceLocation Loc) { if (CGM.getCodeGenOpts().WholeProgramVTables && - CGM.HasHiddenLTOVisibility(RD)) { + !CGM.IsBitSetBlacklistedRecord(RD)) { llvm::Metadata *MD = CGM.CreateMetadataIdentifierForType(QualType(RD->getTypeForDecl(), 0)); llvm::Value *BitSetName = @@ -2565,12 +2565,7 @@ void CodeGenFunction::EmitVTablePtrCheck(const CXXRecordDecl *RD, llvm::Value *VTable, CFITypeCheckKind TCK, SourceLocation Loc) { - if (!CGM.getCodeGenOpts().SanitizeCfiCrossDso && - !CGM.HasHiddenLTOVisibility(RD)) - return; - - std::string TypeName = RD->getQualifiedNameAsString(); - if (getContext().getSanitizerBlacklist().isBlacklistedType(TypeName)) + if (CGM.IsBitSetBlacklistedRecord(RD)) return; SanitizerScope SanScope(this); diff --git a/clang/lib/CodeGen/CGVTables.cpp b/clang/lib/CodeGen/CGVTables.cpp index 478164e273b..f139e2c8504 100644 --- a/clang/lib/CodeGen/CGVTables.cpp +++ b/clang/lib/CodeGen/CGVTables.cpp @@ -902,43 +902,34 @@ void CodeGenModule::EmitDeferredVTables() { DeferredVTables.clear(); } -bool CodeGenModule::HasHiddenLTOVisibility(const CXXRecordDecl *RD) { - LinkageInfo LV = RD->getLinkageAndVisibility(); - if (!isExternallyVisible(LV.getLinkage())) - return true; - - if (RD->hasAttr<LTOVisibilityPublicAttr>() || RD->hasAttr<UuidAttr>()) - return false; +bool CodeGenModule::NeedVTableBitSets() { + return getCodeGenOpts().WholeProgramVTables || + getLangOpts().Sanitize.has(SanitizerKind::CFIVCall) || + getLangOpts().Sanitize.has(SanitizerKind::CFINVCall) || + getLangOpts().Sanitize.has(SanitizerKind::CFIDerivedCast) || + getLangOpts().Sanitize.has(SanitizerKind::CFIUnrelatedCast); +} - if (getTriple().isOSBinFormatCOFF()) { - if (RD->hasAttr<DLLExportAttr>() || RD->hasAttr<DLLImportAttr>()) - return false; - } else { - if (LV.getVisibility() != HiddenVisibility) - return false; - } +bool CodeGenModule::IsBitSetBlacklistedRecord(const CXXRecordDecl *RD) { + std::string TypeName = RD->getQualifiedNameAsString(); + auto isInBlacklist = [&](const SanitizerBlacklist &BL) { + if (RD->hasAttr<UuidAttr>() && BL.isBlacklistedType("attr:uuid")) + return true; - if (getCodeGenOpts().LTOVisibilityPublicStd) { - const DeclContext *DC = RD; - while (1) { - auto *D = cast<Decl>(DC); - DC = DC->getParent(); - if (isa<TranslationUnitDecl>(DC->getRedeclContext())) { - if (auto *ND = dyn_cast<NamespaceDecl>(D)) - if (const IdentifierInfo *II = ND->getIdentifier()) - if (II->isStr("std") || II->isStr("stdext")) - return false; - break; - } - } - } + return BL.isBlacklistedType(TypeName); + }; - return true; + return isInBlacklist(WholeProgramVTablesBlacklist) || + ((LangOpts.Sanitize.has(SanitizerKind::CFIVCall) || + LangOpts.Sanitize.has(SanitizerKind::CFINVCall) || + LangOpts.Sanitize.has(SanitizerKind::CFIDerivedCast) || + LangOpts.Sanitize.has(SanitizerKind::CFIUnrelatedCast)) && + isInBlacklist(getContext().getSanitizerBlacklist())); } void CodeGenModule::EmitVTableBitSetEntries(llvm::GlobalVariable *VTable, const VTableLayout &VTLayout) { - if (!getCodeGenOpts().PrepareForLTO) + if (!NeedVTableBitSets()) return; CharUnits PointerWidth = @@ -947,8 +938,12 @@ void CodeGenModule::EmitVTableBitSetEntries(llvm::GlobalVariable *VTable, typedef std::pair<const CXXRecordDecl *, unsigned> BSEntry; std::vector<BSEntry> BitsetEntries; // Create a bit set entry for each address point. - for (auto &&AP : VTLayout.getAddressPoints()) + for (auto &&AP : VTLayout.getAddressPoints()) { + if (IsBitSetBlacklistedRecord(AP.first.getBase())) + continue; + BitsetEntries.push_back(std::make_pair(AP.first.getBase(), AP.second)); + } // Sort the bit set entries for determinism. std::sort(BitsetEntries.begin(), BitsetEntries.end(), diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 8ff99a6c404..64fe3652a9d 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -88,7 +88,9 @@ CodeGenModule::CodeGenModule(ASTContext &C, const HeaderSearchOptions &HSO, PreprocessorOpts(PPO), CodeGenOpts(CGO), TheModule(M), Diags(diags), Target(C.getTargetInfo()), ABI(createCXXABI(*this)), VMContext(M.getContext()), Types(*this), VTables(*this), - SanitizerMD(new SanitizerMetadata(*this)) { + SanitizerMD(new SanitizerMetadata(*this)), + WholeProgramVTablesBlacklist(CGO.WholeProgramVTablesBlacklistFiles, + C.getSourceManager()) { // Initialize the type cache. llvm::LLVMContext &LLVMContext = M.getContext(); diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index a75e4aa2a32..34d1111889a 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -490,6 +490,8 @@ private: /// MDNodes. llvm::DenseMap<QualType, llvm::Metadata *> MetadataIdMap; + SanitizerBlacklist WholeProgramVTablesBlacklist; + public: CodeGenModule(ASTContext &C, const HeaderSearchOptions &headersearchopts, const PreprocessorOptions &ppopts, @@ -1113,10 +1115,12 @@ public: void EmitOMPDeclareReduction(const OMPDeclareReductionDecl *D, CodeGenFunction *CGF = nullptr); - /// Returns whether the given record has hidden LTO visibility and therefore - /// may participate in (single-module) CFI and whole-program vtable - /// optimization. - bool HasHiddenLTOVisibility(const CXXRecordDecl *RD); + /// Returns whether we need bit sets attached to vtables. + bool NeedVTableBitSets(); + + /// Returns whether the given record is blacklisted from whole-program + /// transformations (i.e. CFI or whole-program vtable optimization). + bool IsBitSetBlacklistedRecord(const CXXRecordDecl *RD); /// Emit bit set entries for the given vtable using the given layout if /// vptr CFI is enabled. diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp index 0e15f5054d8..e578863bfc3 100644 --- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp +++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp @@ -1503,7 +1503,7 @@ void MicrosoftCXXABI::EmitDestructorCall(CodeGenFunction &CGF, void MicrosoftCXXABI::emitVTableBitSetEntries(VPtrInfo *Info, const CXXRecordDecl *RD, llvm::GlobalVariable *VTable) { - if (!CGM.getCodeGenOpts().PrepareForLTO) + if (!CGM.NeedVTableBitSets()) return; llvm::NamedMDNode *BitsetsMD = @@ -1519,13 +1519,15 @@ void MicrosoftCXXABI::emitVTableBitSetEntries(VPtrInfo *Info, : CharUnits::Zero(); if (Info->PathToBaseWithVPtr.empty()) { - CGM.CreateVTableBitSetEntry(BitsetsMD, VTable, AddressPoint, RD); + if (!CGM.IsBitSetBlacklistedRecord(RD)) + CGM.CreateVTableBitSetEntry(BitsetsMD, VTable, AddressPoint, RD); return; } // Add a bitset entry for the least derived base belonging to this vftable. - CGM.CreateVTableBitSetEntry(BitsetsMD, VTable, AddressPoint, - Info->PathToBaseWithVPtr.back()); + if (!CGM.IsBitSetBlacklistedRecord(Info->PathToBaseWithVPtr.back())) + CGM.CreateVTableBitSetEntry(BitsetsMD, VTable, AddressPoint, + Info->PathToBaseWithVPtr.back()); // Add a bitset entry for each derived class that is laid out at the same // offset as the least derived base. @@ -1543,11 +1545,12 @@ void MicrosoftCXXABI::emitVTableBitSetEntries(VPtrInfo *Info, Offset = VBI->second.VBaseOffset; if (!Offset.isZero()) return; - CGM.CreateVTableBitSetEntry(BitsetsMD, VTable, AddressPoint, DerivedRD); + if (!CGM.IsBitSetBlacklistedRecord(DerivedRD)) + CGM.CreateVTableBitSetEntry(BitsetsMD, VTable, AddressPoint, DerivedRD); } // Finally do the same for the most derived class. - if (Info->FullOffsetInMDC.isZero()) + if (Info->FullOffsetInMDC.isZero() && !CGM.IsBitSetBlacklistedRecord(RD)) CGM.CreateVTableBitSetEntry(BitsetsMD, VTable, AddressPoint, RD); } @@ -1816,7 +1819,7 @@ llvm::Value *MicrosoftCXXABI::getVirtualFunctionPointer(CodeGenFunction &CGF, MicrosoftVTableContext::MethodVFTableLocation ML = CGM.getMicrosoftVTableContext().getMethodVFTableLocation(GD); - if (CGM.getCodeGenOpts().PrepareForLTO) + if (CGM.NeedVTableBitSets()) CGF.EmitBitSetCodeForVCall(getClassAtVTableLocation(getContext(), GD, ML), VTable, Loc); |