summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-cfi-verify
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools/llvm-cfi-verify')
-rw-r--r--llvm/tools/llvm-cfi-verify/lib/FileAnalysis.cpp5
-rw-r--r--llvm/tools/llvm-cfi-verify/lib/FileAnalysis.h4
-rw-r--r--llvm/tools/llvm-cfi-verify/lib/GraphBuilder.cpp24
-rw-r--r--llvm/tools/llvm-cfi-verify/lib/GraphBuilder.h3
-rw-r--r--llvm/tools/llvm-cfi-verify/llvm-cfi-verify.cpp14
5 files changed, 46 insertions, 4 deletions
diff --git a/llvm/tools/llvm-cfi-verify/lib/FileAnalysis.cpp b/llvm/tools/llvm-cfi-verify/lib/FileAnalysis.cpp
index 42de8cb4f7d..8f3a6837cfa 100644
--- a/llvm/tools/llvm-cfi-verify/lib/FileAnalysis.cpp
+++ b/llvm/tools/llvm-cfi-verify/lib/FileAnalysis.cpp
@@ -273,6 +273,11 @@ FileAnalysis::validateCFIProtection(const GraphResult &Graph) const {
return CFIProtectionStatus::PROTECTED;
}
+void FileAnalysis::printInstruction(const Instr &InstrMeta,
+ raw_ostream &OS) const {
+ Printer->printInst(&InstrMeta.Instruction, OS, "", *SubtargetInfo.get());
+}
+
Error FileAnalysis::initialiseDisassemblyMembers() {
std::string TripleName = ObjectTriple.getTriple();
ArchName = "";
diff --git a/llvm/tools/llvm-cfi-verify/lib/FileAnalysis.h b/llvm/tools/llvm-cfi-verify/lib/FileAnalysis.h
index dfeff13863b..820c3683540 100644
--- a/llvm/tools/llvm-cfi-verify/lib/FileAnalysis.h
+++ b/llvm/tools/llvm-cfi-verify/lib/FileAnalysis.h
@@ -145,6 +145,10 @@ public:
// flow instruction in this file.
CFIProtectionStatus validateCFIProtection(const GraphResult &Graph) const;
+ // Prints an instruction to the provided stream using this object's pretty-
+ // printers.
+ void printInstruction(const Instr &InstrMeta, raw_ostream &OS) const;
+
protected:
// Construct a blank object with the provided triple and features. Used in
// testing, where a sub class will dependency inject protected methods to
diff --git a/llvm/tools/llvm-cfi-verify/lib/GraphBuilder.cpp b/llvm/tools/llvm-cfi-verify/lib/GraphBuilder.cpp
index 7366ff0cf30..ff921713302 100644
--- a/llvm/tools/llvm-cfi-verify/lib/GraphBuilder.cpp
+++ b/llvm/tools/llvm-cfi-verify/lib/GraphBuilder.cpp
@@ -71,6 +71,30 @@ std::vector<uint64_t> GraphResult::flattenAddress(uint64_t Address) const {
return Addresses;
}
+void printPairToDOT(const FileAnalysis &Analysis, raw_ostream &OS,
+ uint64_t From, uint64_t To) {
+ OS << " \"" << format_hex(From, 2) << ": ";
+ Analysis.printInstruction(Analysis.getInstructionOrDie(From), OS);
+ OS << "\" -> \"" << format_hex(To, 2) << ": ";
+ Analysis.printInstruction(Analysis.getInstructionOrDie(To), OS);
+ OS << "\"\n";
+}
+
+void GraphResult::printToDOT(const FileAnalysis &Analysis,
+ raw_ostream &OS) const {
+ std::map<uint64_t, uint64_t> SortedIntermediateNodes(
+ IntermediateNodes.begin(), IntermediateNodes.end());
+ OS << "digraph graph_" << format_hex(BaseAddress, 2) << " {\n";
+ for (const auto &KV : SortedIntermediateNodes)
+ printPairToDOT(Analysis, OS, KV.first, KV.second);
+
+ for (auto &BranchNode : ConditionalBranchNodes) {
+ for (auto &V : {BranchNode.Target, BranchNode.Fallthrough})
+ printPairToDOT(Analysis, OS, BranchNode.Address, V);
+ }
+ OS << "}\n";
+}
+
GraphResult GraphBuilder::buildFlowGraph(const FileAnalysis &Analysis,
uint64_t Address) {
GraphResult Result;
diff --git a/llvm/tools/llvm-cfi-verify/lib/GraphBuilder.h b/llvm/tools/llvm-cfi-verify/lib/GraphBuilder.h
index 12d9c95e3cf..d1ce5096ed9 100644
--- a/llvm/tools/llvm-cfi-verify/lib/GraphBuilder.h
+++ b/llvm/tools/llvm-cfi-verify/lib/GraphBuilder.h
@@ -89,6 +89,9 @@ struct GraphResult {
// base. The provided address must be part of this graph, and must not be a
// conditional branch.
std::vector<uint64_t> flattenAddress(uint64_t Address) const;
+
+ // Print the DOT representation of this result.
+ void printToDOT(const FileAnalysis &Analysis, raw_ostream &OS) const;
};
class GraphBuilder {
diff --git a/llvm/tools/llvm-cfi-verify/llvm-cfi-verify.cpp b/llvm/tools/llvm-cfi-verify/llvm-cfi-verify.cpp
index 8ae905e2636..245ce05a254 100644
--- a/llvm/tools/llvm-cfi-verify/llvm-cfi-verify.cpp
+++ b/llvm/tools/llvm-cfi-verify/llvm-cfi-verify.cpp
@@ -37,6 +37,10 @@ cl::opt<std::string> InputFilename(cl::Positional, cl::desc("<input file>"),
cl::opt<std::string> BlacklistFilename(cl::Positional,
cl::desc("[blacklist file]"),
cl::init("-"));
+cl::opt<bool> PrintGraphs(
+ "print-graphs",
+ cl::desc("Print graphs around indirect CF instructions in DOT format."),
+ cl::init(false));
ExitOnError ExitOnErr;
@@ -62,10 +66,12 @@ void printIndirectCFInstructions(FileAnalysis &Analysis,
else
outs() << "U ";
- outs() << format_hex(Address, 2) << " | "
- << Analysis.getMCInstrInfo()->getName(
- InstrMeta.Instruction.getOpcode())
- << " \n";
+ outs() << format_hex(Address, 2) << " | ";
+ Analysis.printInstruction(InstrMeta, outs());
+ outs() << " \n";
+
+ if (PrintGraphs)
+ Graph.printToDOT(Analysis, outs());
if (IgnoreDWARFFlag) {
if (CFIProtected)
OpenPOWER on IntegriCloud