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
This commit is contained in:
@@ -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));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user