diff options
author | Mitch Phillips <mitchphillips@outlook.com> | 2017-11-10 21:00:22 +0000 |
---|---|---|
committer | Mitch Phillips <mitchphillips@outlook.com> | 2017-11-10 21:00:22 +0000 |
commit | 3b9ea32ef83247090205891af305d98a3aa5c975 (patch) | |
tree | db95d9de57ea5c37668ac3abb87d181a56b10b7c /llvm/tools/llvm-cfi-verify/lib/FileAnalysis.cpp | |
parent | 3f0f650f498d97516745678b304a1649c3b2450f (diff) | |
download | bcm5719-llvm-3b9ea32ef83247090205891af305d98a3aa5c975.tar.gz bcm5719-llvm-3b9ea32ef83247090205891af305d98a3aa5c975.zip |
[cfi-verify] Made FileAnalysis operate on a GraphResult rather than build one and validate it.
Refactors the behaviour of building graphs out of FileAnalysis, allowing for analysis of the GraphResult by the callee without having to rebuild the graph. Means when we want to analyse the constructed graph (planned for later revisions), we don't do repeated work.
Also makes CFI verification in FileAnalysis now return an enum that allows us to differentiate why something failed, not just that it did/didn't fail.
Reviewers: vlad.tsyrklevich
Subscribers: kcc, pcc, llvm-commits
Differential Revision: https://reviews.llvm.org/D39764
llvm-svn: 317927
Diffstat (limited to 'llvm/tools/llvm-cfi-verify/lib/FileAnalysis.cpp')
-rw-r--r-- | llvm/tools/llvm-cfi-verify/lib/FileAnalysis.cpp | 71 |
1 files changed, 44 insertions, 27 deletions
diff --git a/llvm/tools/llvm-cfi-verify/lib/FileAnalysis.cpp b/llvm/tools/llvm-cfi-verify/lib/FileAnalysis.cpp index 863bbfb045e..42de8cb4f7d 100644 --- a/llvm/tools/llvm-cfi-verify/lib/FileAnalysis.cpp +++ b/llvm/tools/llvm-cfi-verify/lib/FileAnalysis.cpp @@ -54,6 +54,22 @@ static cl::opt<bool, true> IgnoreDWARFArg( "will result in false positives for 'CFI unprotected' instructions."), cl::location(IgnoreDWARFFlag), cl::init(false)); +StringRef stringCFIProtectionStatus(CFIProtectionStatus Status) { + switch (Status) { + case CFIProtectionStatus::PROTECTED: + return "PROTECTED"; + case CFIProtectionStatus::FAIL_NOT_INDIRECT_CF: + return "FAIL_NOT_INDIRECT_CF"; + case CFIProtectionStatus::FAIL_ORPHANS: + return "FAIL_ORPHANS"; + case CFIProtectionStatus::FAIL_BAD_CONDITIONAL_BRANCH: + return "FAIL_BAD_CONDITIONAL_BRANCH"; + case CFIProtectionStatus::FAIL_INVALID_INSTRUCTION: + return "FAIL_INVALID_INSTRUCTION"; + } + llvm_unreachable("Attempted to stringify an unknown enum value."); +} + Expected<FileAnalysis> FileAnalysis::Create(StringRef Filename) { // Open the filename provided. Expected<object::OwningBinary<object::Binary>> BinaryOrErr = @@ -89,32 +105,6 @@ 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 = @@ -254,7 +244,34 @@ const MCInstrAnalysis *FileAnalysis::getMCInstrAnalysis() const { return MIA.get(); } -LLVMSymbolizer &FileAnalysis::getSymbolizer() { return *Symbolizer; } +Expected<DIInliningInfo> FileAnalysis::symbolizeInlinedCode(uint64_t Address) { + assert(Symbolizer != nullptr && "Symbolizer is invalid."); + return Symbolizer->symbolizeInlinedCode(Object->getFileName(), Address); +} + +CFIProtectionStatus +FileAnalysis::validateCFIProtection(const GraphResult &Graph) const { + const Instr *InstrMetaPtr = getInstruction(Graph.BaseAddress); + if (!InstrMetaPtr) + return CFIProtectionStatus::FAIL_INVALID_INSTRUCTION; + + const auto &InstrDesc = MII->get(InstrMetaPtr->Instruction.getOpcode()); + if (!InstrDesc.mayAffectControlFlow(InstrMetaPtr->Instruction, *RegisterInfo)) + return CFIProtectionStatus::FAIL_NOT_INDIRECT_CF; + + if (!usesRegisterOperand(*InstrMetaPtr)) + return CFIProtectionStatus::FAIL_NOT_INDIRECT_CF; + + if (!Graph.OrphanedNodes.empty()) + return CFIProtectionStatus::FAIL_ORPHANS; + + for (const auto &BranchNode : Graph.ConditionalBranchNodes) { + if (!BranchNode.CFIProtection) + return CFIProtectionStatus::FAIL_BAD_CONDITIONAL_BRANCH; + } + + return CFIProtectionStatus::PROTECTED; +} Error FileAnalysis::initialiseDisassemblyMembers() { std::string TripleName = ObjectTriple.getTriple(); |