Add FileVerifier::isCFIProtected().
Add a CFI protection check that is implemented by building a graph and inspecting the output to deduce if the indirect CF instruction is CFI protected. Also added the output of this instruction to printIndirectInstructions().
Reviewers: vlad.tsyrklevich
Subscribers: llvm-commits, kcc, pcc, mgorny
Differential Revision: https://reviews.llvm.org/D38428
llvm-svn: 316610
diff --git a/llvm/tools/llvm-cfi-verify/lib/FileAnalysis.cpp b/llvm/tools/llvm-cfi-verify/lib/FileAnalysis.cpp
index 761b2ab..928571b 100644
--- a/llvm/tools/llvm-cfi-verify/lib/FileAnalysis.cpp
+++ b/llvm/tools/llvm-cfi-verify/lib/FileAnalysis.cpp
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include "FileAnalysis.h"
+#include "GraphBuilder.h"
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/MC/MCAsmInfo.h"
@@ -76,6 +77,32 @@
const SubtargetFeatures &Features)
: ObjectTriple(ObjectTriple), Features(Features) {}
+bool FileAnalysis::isIndirectInstructionCFIProtected(uint64_t Address) const {
+ const Instr *InstrMetaPtr = getInstruction(Address);
+ if (!InstrMetaPtr)
+ return false;
+
+ const auto &InstrDesc = MII->get(InstrMetaPtr->Instruction.getOpcode());
+
+ if (!InstrDesc.mayAffectControlFlow(InstrMetaPtr->Instruction, *RegisterInfo))
+ return false;
+
+ if (!usesRegisterOperand(*InstrMetaPtr))
+ return false;
+
+ auto Flows = GraphBuilder::buildFlowGraph(*this, Address);
+
+ if (!Flows.OrphanedNodes.empty())
+ return false;
+
+ for (const auto &BranchNode : Flows.ConditionalBranchNodes) {
+ if (!BranchNode.CFIProtection)
+ return false;
+ }
+
+ return true;
+}
+
const Instr *
FileAnalysis::getPrevInstructionSequential(const Instr &InstrMeta) const {
std::map<uint64_t, Instr>::const_iterator KV =
@@ -226,7 +253,8 @@
if (!ObjectTarget)
return make_error<UnsupportedDisassembly>(
(Twine("Couldn't find target \"") + ObjectTriple.getTriple() +
- "\", failed with error: " + ErrorString).str());
+ "\", failed with error: " + ErrorString)
+ .str());
RegisterInfo.reset(ObjectTarget->createMCRegInfo(TripleName));
if (!RegisterInfo)