diff options
author | Peter Collingbourne <peter@pcc.me.uk> | 2015-09-10 02:17:40 +0000 |
---|---|---|
committer | Peter Collingbourne <peter@pcc.me.uk> | 2015-09-10 02:17:40 +0000 |
commit | 2c7f7e31c4c0afc84f8614a48ef7e1449b458c58 (patch) | |
tree | c086262a5904b3d67a23e8baa1d5ae186989ad56 /clang/lib/CodeGen/CGVTables.cpp | |
parent | d3b904d440fee3c869d8c8a2c33dffd8bc82b384 (diff) | |
download | llvm-2c7f7e31c4c0afc84f8614a48ef7e1449b458c58.zip llvm-2c7f7e31c4c0afc84f8614a48ef7e1449b458c58.tar.gz llvm-2c7f7e31c4c0afc84f8614a48ef7e1449b458c58.tar.bz2 |
CFI: Introduce -fsanitize=cfi-icall flag.
This flag causes the compiler to emit bit set entries for functions as well
as runtime bitset checks at indirect call sites. Depends on the new function
bitset mechanism.
Differential Revision: http://reviews.llvm.org/D11857
llvm-svn: 247238
Diffstat (limited to 'clang/lib/CodeGen/CGVTables.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGVTables.cpp | 38 |
1 files changed, 21 insertions, 17 deletions
diff --git a/clang/lib/CodeGen/CGVTables.cpp b/clang/lib/CodeGen/CGVTables.cpp index 6aa624e..4c3202c 100644 --- a/clang/lib/CodeGen/CGVTables.cpp +++ b/clang/lib/CodeGen/CGVTables.cpp @@ -893,41 +893,45 @@ void CodeGenModule::EmitVTableBitSetEntries(llvm::GlobalVariable *VTable, CharUnits PointerWidth = Context.toCharUnitsFromBits(Context.getTargetInfo().getPointerWidth(0)); - std::vector<llvm::MDTuple *> BitsetEntries; + 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()) { if (IsCFIBlacklistedRecord(AP.first.getBase())) continue; - BitsetEntries.push_back(CreateVTableBitSetEntry( - VTable, PointerWidth * AP.second, AP.first.getBase())); + BitsetEntries.push_back(std::make_pair(AP.first.getBase(), AP.second)); } // Sort the bit set entries for determinism. - std::sort(BitsetEntries.begin(), BitsetEntries.end(), [](llvm::MDTuple *T1, - llvm::MDTuple *T2) { - if (T1 == T2) + std::sort(BitsetEntries.begin(), BitsetEntries.end(), + [this](const BSEntry &E1, const BSEntry &E2) { + if (&E1 == &E2) return false; - StringRef S1 = cast<llvm::MDString>(T1->getOperand(0))->getString(); - StringRef S2 = cast<llvm::MDString>(T2->getOperand(0))->getString(); + std::string S1; + llvm::raw_string_ostream O1(S1); + getCXXABI().getMangleContext().mangleTypeName( + QualType(E1.first->getTypeForDecl(), 0), O1); + O1.flush(); + + std::string S2; + llvm::raw_string_ostream O2(S2); + getCXXABI().getMangleContext().mangleTypeName( + QualType(E2.first->getTypeForDecl(), 0), O2); + O2.flush(); + if (S1 < S2) return true; if (S1 != S2) return false; - uint64_t Offset1 = cast<llvm::ConstantInt>( - cast<llvm::ConstantAsMetadata>(T1->getOperand(2)) - ->getValue())->getZExtValue(); - uint64_t Offset2 = cast<llvm::ConstantInt>( - cast<llvm::ConstantAsMetadata>(T2->getOperand(2)) - ->getValue())->getZExtValue(); - assert(Offset1 != Offset2); - return Offset1 < Offset2; + return E1.second < E2.second; }); llvm::NamedMDNode *BitsetsMD = getModule().getOrInsertNamedMetadata("llvm.bitsets"); for (auto BitsetEntry : BitsetEntries) - BitsetsMD->addOperand(BitsetEntry); + BitsetsMD->addOperand(CreateVTableBitSetEntry( + VTable, PointerWidth * BitsetEntry.second, BitsetEntry.first)); } |