summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorMitch Phillips <mitchphillips@outlook.com>2017-10-25 21:21:16 +0000
committerMitch Phillips <mitchphillips@outlook.com>2017-10-25 21:21:16 +0000
commit46254ad82346c14682f5f827c5bb77d3c2cdefff (patch)
tree4a125540d2db99ac182b26f7475d448d3b2c0114 /tools
parent3498a4cb172deb13502233da11b6af817af51f21 (diff)
downloadllvm-46254ad82346c14682f5f827c5bb77d3c2cdefff.tar.gz
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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@316610 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools')
-rw-r--r--tools/llvm-cfi-verify/lib/FileAnalysis.cpp30
-rw-r--r--tools/llvm-cfi-verify/lib/FileAnalysis.h6
-rw-r--r--tools/llvm-cfi-verify/llvm-cfi-verify.cpp2
3 files changed, 37 insertions, 1 deletions
diff --git a/tools/llvm-cfi-verify/lib/FileAnalysis.cpp b/tools/llvm-cfi-verify/lib/FileAnalysis.cpp
index 761b2ab1037f..928571bfd0a4 100644
--- a/tools/llvm-cfi-verify/lib/FileAnalysis.cpp
+++ b/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 @@ FileAnalysis::FileAnalysis(const Triple &ObjectTriple,
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 @@ Error FileAnalysis::initialiseDisassemblyMembers() {
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)
diff --git a/tools/llvm-cfi-verify/lib/FileAnalysis.h b/tools/llvm-cfi-verify/lib/FileAnalysis.h
index 803eeee97e04..1ed575bb9e43 100644
--- a/tools/llvm-cfi-verify/lib/FileAnalysis.h
+++ b/tools/llvm-cfi-verify/lib/FileAnalysis.h
@@ -66,6 +66,12 @@ public:
FileAnalysis(const FileAnalysis &) = delete;
FileAnalysis(FileAnalysis &&Other) = default;
+ // Check whether the provided instruction is CFI protected in this file.
+ // Returns false if this instruction doesn't exist in this file, if it's not
+ // an indirect control flow instruction, or isn't CFI protected. Returns true
+ // otherwise.
+ bool isIndirectInstructionCFIProtected(uint64_t Address) const;
+
// Returns the instruction at the provided address. Returns nullptr if there
// is no instruction at the provided address.
const Instr *getInstruction(uint64_t Address) const;
diff --git a/tools/llvm-cfi-verify/llvm-cfi-verify.cpp b/tools/llvm-cfi-verify/llvm-cfi-verify.cpp
index c363cb1a6cba..00324ed0eb41 100644
--- a/tools/llvm-cfi-verify/llvm-cfi-verify.cpp
+++ b/tools/llvm-cfi-verify/llvm-cfi-verify.cpp
@@ -43,6 +43,8 @@ void printIndirectCFInstructions(const FileAnalysis &Verifier) {
<< " ";
InstrMeta.Instruction.print(outs());
outs() << "\n";
+ outs() << " Protected? "
+ << Verifier.isIndirectInstructionCFIProtected(Address) << "\n";
}
}