[llvm] r318211 - [cfi-verify] Add DOT graph printing for GraphResult objects.
Mitch Phillips via llvm-commits
llvm-commits at lists.llvm.org
Tue Nov 14 14:43:13 PST 2017
Author: hctim
Date: Tue Nov 14 14:43:13 2017
New Revision: 318211
URL: http://llvm.org/viewvc/llvm-project?rev=318211&view=rev
Log:
[cfi-verify] Add DOT graph printing for GraphResult objects.
Allows users to view GraphResult objects in a DOT directed-graph format. This feature can be turned on through the --print-graphs flag.
Also enabled pretty-printing of instructions in output. Together these features make analysis of unprotected CF instructions much easier by providing a visual control flow graph.
Reviewers: pcc
Subscribers: llvm-commits, kcc, vlad.tsyrklevich
Differential Revision: https://reviews.llvm.org/D39819
Added:
llvm/trunk/test/tools/llvm-cfi-verify/X86/dot-printing.s
Modified:
llvm/trunk/tools/llvm-cfi-verify/lib/FileAnalysis.cpp
llvm/trunk/tools/llvm-cfi-verify/lib/FileAnalysis.h
llvm/trunk/tools/llvm-cfi-verify/lib/GraphBuilder.cpp
llvm/trunk/tools/llvm-cfi-verify/lib/GraphBuilder.h
llvm/trunk/tools/llvm-cfi-verify/llvm-cfi-verify.cpp
Added: llvm/trunk/test/tools/llvm-cfi-verify/X86/dot-printing.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-cfi-verify/X86/dot-printing.s?rev=318211&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-cfi-verify/X86/dot-printing.s (added)
+++ llvm/trunk/test/tools/llvm-cfi-verify/X86/dot-printing.s Tue Nov 14 14:43:13 2017
@@ -0,0 +1,18 @@
+# RUN: llvm-mc %S/Inputs/protected-lineinfo.s -filetype obj \
+# RUN: -triple x86_64-linux-elf -o %t.o
+# RUN: llvm-cfi-verify -print-graphs %t.o | FileCheck %s
+
+# The expected output is as follows:
+# P 0x7b | callq *%rax
+# digraph graph_0x7b {
+# "0x77: jbe 2" -> "0x7b: callq *%rax"
+# "0x77: jbe 2" -> "0x79: ud2"
+# }
+# 0x7b = tiny.cc:11:3 (main)
+
+# CHECK: {{^P.*callq +\*%rax.*$}}
+# CHECK-NEXT: digraph
+# CHECK-NEXT: {{^.*jbe.*->.*callq \*%rax}}
+# CHECK-NEXT: {{^.*jbe.*->.*ud2}}
+# CHECK-NEXT: }
+# CHECK-NEXT: tiny.cc:11
Modified: llvm/trunk/tools/llvm-cfi-verify/lib/FileAnalysis.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-cfi-verify/lib/FileAnalysis.cpp?rev=318211&r1=318210&r2=318211&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-cfi-verify/lib/FileAnalysis.cpp (original)
+++ llvm/trunk/tools/llvm-cfi-verify/lib/FileAnalysis.cpp Tue Nov 14 14:43:13 2017
@@ -273,6 +273,11 @@ FileAnalysis::validateCFIProtection(cons
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 = "";
Modified: llvm/trunk/tools/llvm-cfi-verify/lib/FileAnalysis.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-cfi-verify/lib/FileAnalysis.h?rev=318211&r1=318210&r2=318211&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-cfi-verify/lib/FileAnalysis.h (original)
+++ llvm/trunk/tools/llvm-cfi-verify/lib/FileAnalysis.h Tue Nov 14 14:43:13 2017
@@ -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
Modified: llvm/trunk/tools/llvm-cfi-verify/lib/GraphBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-cfi-verify/lib/GraphBuilder.cpp?rev=318211&r1=318210&r2=318211&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-cfi-verify/lib/GraphBuilder.cpp (original)
+++ llvm/trunk/tools/llvm-cfi-verify/lib/GraphBuilder.cpp Tue Nov 14 14:43:13 2017
@@ -71,6 +71,30 @@ std::vector<uint64_t> GraphResult::flatt
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;
Modified: llvm/trunk/tools/llvm-cfi-verify/lib/GraphBuilder.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-cfi-verify/lib/GraphBuilder.h?rev=318211&r1=318210&r2=318211&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-cfi-verify/lib/GraphBuilder.h (original)
+++ llvm/trunk/tools/llvm-cfi-verify/lib/GraphBuilder.h Tue Nov 14 14:43:13 2017
@@ -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 {
Modified: llvm/trunk/tools/llvm-cfi-verify/llvm-cfi-verify.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-cfi-verify/llvm-cfi-verify.cpp?rev=318211&r1=318210&r2=318211&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-cfi-verify/llvm-cfi-verify.cpp (original)
+++ llvm/trunk/tools/llvm-cfi-verify/llvm-cfi-verify.cpp Tue Nov 14 14:43:13 2017
@@ -37,6 +37,10 @@ cl::opt<std::string> InputFilename(cl::P
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(FileAna
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)
More information about the llvm-commits
mailing list