summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-cfi-verify/lib/FileAnalysis.cpp
diff options
context:
space:
mode:
authorVlad Tsyrklevich <vlad@tsyrklevich.net>2017-10-11 23:17:29 +0000
committerVlad Tsyrklevich <vlad@tsyrklevich.net>2017-10-11 23:17:29 +0000
commit0ee26324039e128ec2813a0ccc43803910bea451 (patch)
treef30ce78ac2d4d3f6e3f690e6a39126edf1f5520a /llvm/tools/llvm-cfi-verify/lib/FileAnalysis.cpp
parentbffdd9aa397cd99d36e3c0c0fa4f09642de16101 (diff)
downloadbcm5719-llvm-0ee26324039e128ec2813a0ccc43803910bea451.tar.gz
bcm5719-llvm-0ee26324039e128ec2813a0ccc43803910bea451.zip
MC Helpers for llvm-cfi-verify.
Add instruction analysis and machinecode traversal helpers in preparation for control flow graph generation implementation. Reviewers: vlad.tsyrklevich Reviewed By: vlad.tsyrklevich Subscribers: mgorny, llvm-commits, pcc, kcc Differential Revision: https://reviews.llvm.org/D38424 llvm-svn: 315528
Diffstat (limited to 'llvm/tools/llvm-cfi-verify/lib/FileAnalysis.cpp')
-rw-r--r--llvm/tools/llvm-cfi-verify/lib/FileAnalysis.cpp77
1 files changed, 77 insertions, 0 deletions
diff --git a/llvm/tools/llvm-cfi-verify/lib/FileAnalysis.cpp b/llvm/tools/llvm-cfi-verify/lib/FileAnalysis.cpp
index 6a275ce83c1..8439a06a24d 100644
--- a/llvm/tools/llvm-cfi-verify/lib/FileAnalysis.cpp
+++ b/llvm/tools/llvm-cfi-verify/lib/FileAnalysis.cpp
@@ -124,6 +124,83 @@ const Instr &FileAnalysis::getInstructionOrDie(uint64_t Address) const {
return InstrKV->second;
}
+bool FileAnalysis::isCFITrap(const Instr &InstrMeta) const {
+ return MII->getName(InstrMeta.Instruction.getOpcode()) == "TRAP";
+}
+
+bool FileAnalysis::canFallThrough(const Instr &InstrMeta) const {
+ if (!InstrMeta.Valid)
+ return false;
+
+ if (isCFITrap(InstrMeta))
+ return false;
+
+ const auto &InstrDesc = MII->get(InstrMeta.Instruction.getOpcode());
+ if (InstrDesc.mayAffectControlFlow(InstrMeta.Instruction, *RegisterInfo))
+ return InstrDesc.isConditionalBranch();
+
+ return true;
+}
+
+const Instr *
+FileAnalysis::getDefiniteNextInstruction(const Instr &InstrMeta) const {
+ if (!InstrMeta.Valid)
+ return nullptr;
+
+ if (isCFITrap(InstrMeta))
+ return nullptr;
+
+ const auto &InstrDesc = MII->get(InstrMeta.Instruction.getOpcode());
+ const Instr *NextMetaPtr;
+ if (InstrDesc.mayAffectControlFlow(InstrMeta.Instruction, *RegisterInfo)) {
+ if (InstrDesc.isConditionalBranch())
+ return nullptr;
+
+ uint64_t Target;
+ if (!MIA->evaluateBranch(InstrMeta.Instruction, InstrMeta.VMAddress,
+ InstrMeta.InstructionSize, Target))
+ return nullptr;
+
+ NextMetaPtr = getInstruction(Target);
+ } else {
+ NextMetaPtr =
+ getInstruction(InstrMeta.VMAddress + InstrMeta.InstructionSize);
+ }
+
+ if (!NextMetaPtr || !NextMetaPtr->Valid)
+ return nullptr;
+
+ return NextMetaPtr;
+}
+
+std::set<const Instr *>
+FileAnalysis::getDirectControlFlowXRefs(const Instr &InstrMeta) const {
+ std::set<const Instr *> CFCrossReferences;
+ const Instr *PrevInstruction = getPrevInstructionSequential(InstrMeta);
+
+ if (PrevInstruction && canFallThrough(*PrevInstruction))
+ CFCrossReferences.insert(PrevInstruction);
+
+ const auto &TargetRefsKV = StaticBranchTargetings.find(InstrMeta.VMAddress);
+ if (TargetRefsKV == StaticBranchTargetings.end())
+ return CFCrossReferences;
+
+ for (uint64_t SourceInstrAddress : TargetRefsKV->second) {
+ const auto &SourceInstrKV = Instructions.find(SourceInstrAddress);
+ if (SourceInstrKV == Instructions.end()) {
+ errs() << "Failed to find source instruction at address "
+ << format_hex(SourceInstrAddress, 2)
+ << " for the cross-reference to instruction at address "
+ << format_hex(InstrMeta.VMAddress, 2) << ".\n";
+ continue;
+ }
+
+ CFCrossReferences.insert(&SourceInstrKV->second);
+ }
+
+ return CFCrossReferences;
+}
+
const std::set<uint64_t> &FileAnalysis::getIndirectInstructions() const {
return IndirectInstructions;
}
OpenPOWER on IntegriCloud