summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-cfi-verify/llvm-cfi-verify.cpp
diff options
context:
space:
mode:
authorVlad Tsyrklevich <vlad@tsyrklevich.net>2018-02-01 23:45:18 +0000
committerVlad Tsyrklevich <vlad@tsyrklevich.net>2018-02-01 23:45:18 +0000
commitb2c3ea760320443f9d4360cbd7fcec1a8b3cc28e (patch)
treeb37b94c1dfb543626d9ddfe59bab17e7c998f61c /llvm/tools/llvm-cfi-verify/llvm-cfi-verify.cpp
parente2f8718b5072b47a31084242ac9013946d907580 (diff)
downloadbcm5719-llvm-b2c3ea760320443f9d4360cbd7fcec1a8b3cc28e.tar.gz
bcm5719-llvm-b2c3ea760320443f9d4360cbd7fcec1a8b3cc28e.zip
[cfi-verify] Add blame context printing, and improved print format.
Summary: This update now allows users to specify `--blame-context` and `--blame-context-all` to print source file blame information for the source of the blame. Also updates the inline printing to correctly identify the top of the inlining stack for blame information. Patch by Mitch Phillips! Reviewers: vlad.tsyrklevich Subscribers: llvm-commits, kcc, pcc Differential Revision: https://reviews.llvm.org/D40111 llvm-svn: 324035
Diffstat (limited to 'llvm/tools/llvm-cfi-verify/llvm-cfi-verify.cpp')
-rw-r--r--llvm/tools/llvm-cfi-verify/llvm-cfi-verify.cpp152
1 files changed, 114 insertions, 38 deletions
diff --git a/llvm/tools/llvm-cfi-verify/llvm-cfi-verify.cpp b/llvm/tools/llvm-cfi-verify/llvm-cfi-verify.cpp
index 245ce05a254..b221e5a8332 100644
--- a/llvm/tools/llvm-cfi-verify/llvm-cfi-verify.cpp
+++ b/llvm/tools/llvm-cfi-verify/llvm-cfi-verify.cpp
@@ -41,9 +41,87 @@ cl::opt<bool> PrintGraphs(
"print-graphs",
cl::desc("Print graphs around indirect CF instructions in DOT format."),
cl::init(false));
+cl::opt<unsigned> PrintBlameContext(
+ "blame-context",
+ cl::desc("Print the blame context (if possible) for BAD instructions. This "
+ "specifies the number of lines of context to include, where zero "
+ "disables this feature."),
+ cl::init(0));
+cl::opt<unsigned> PrintBlameContextAll(
+ "blame-context-all",
+ cl::desc("Prints the blame context (if possible) for ALL instructions. "
+ "This specifies the number of lines of context for non-BAD "
+ "instructions (see --blame-context). If --blame-context is "
+ "unspecified, it prints this number of contextual lines for BAD "
+ "instructions as well."),
+ cl::init(0));
+cl::opt<bool> Summarize("summarize", cl::desc("Print the summary only."),
+ cl::init(false));
ExitOnError ExitOnErr;
+void printBlameContext(const DILineInfo &LineInfo, unsigned Context) {
+ auto FileOrErr = MemoryBuffer::getFile(LineInfo.FileName);
+ if (!FileOrErr) {
+ errs() << "Could not open file: " << LineInfo.FileName << "\n";
+ return;
+ }
+
+ std::unique_ptr<MemoryBuffer> File = std::move(FileOrErr.get());
+ SmallVector<StringRef, 100> Lines;
+ File->getBuffer().split(Lines, '\n');
+
+ for (unsigned i = std::max(1l, (long)LineInfo.Line - Context);
+ i <
+ std::min(Lines.size() + 1, (unsigned long)LineInfo.Line + Context + 1);
+ ++i) {
+ if (i == LineInfo.Line)
+ outs() << ">";
+ else
+ outs() << " ";
+
+ outs() << i << ": " << Lines[i - 1] << "\n";
+ }
+}
+
+void printInstructionInformation(const FileAnalysis &Analysis,
+ const Instr &InstrMeta,
+ const GraphResult &Graph,
+ CFIProtectionStatus ProtectionStatus) {
+ outs() << "Instruction: " << format_hex(InstrMeta.VMAddress, 2) << " ("
+ << stringCFIProtectionStatus(ProtectionStatus) << "): ";
+ Analysis.printInstruction(InstrMeta, outs());
+ outs() << " \n";
+
+ if (PrintGraphs)
+ Graph.printToDOT(Analysis, outs());
+}
+
+void printInstructionStatus(unsigned BlameLine, bool CFIProtected,
+ const DILineInfo &LineInfo) {
+ if (BlameLine) {
+ outs() << "Blacklist Match: " << BlacklistFilename << ":" << BlameLine
+ << "\n";
+ if (CFIProtected)
+ outs() << "====> Unexpected Protected\n";
+ else
+ outs() << "====> Expected Unprotected\n";
+
+ if (PrintBlameContextAll)
+ printBlameContext(LineInfo, PrintBlameContextAll);
+ } else {
+ if (CFIProtected) {
+ outs() << "====> Expected Protected\n";
+ if (PrintBlameContextAll)
+ printBlameContext(LineInfo, PrintBlameContextAll);
+ } else {
+ outs() << "====> Unexpected Unprotected (BAD)\n";
+ if (PrintBlameContext)
+ printBlameContext(LineInfo, PrintBlameContext);
+ }
+ }
+}
+
void printIndirectCFInstructions(FileAnalysis &Analysis,
const SpecialCaseList *SpecialCaseList) {
uint64_t ExpectedProtected = 0;
@@ -61,17 +139,10 @@ void printIndirectCFInstructions(FileAnalysis &Analysis,
Analysis.validateCFIProtection(Graph);
bool CFIProtected = (ProtectionStatus == CFIProtectionStatus::PROTECTED);
- if (CFIProtected)
- outs() << "P ";
- else
- outs() << "U ";
-
- outs() << format_hex(Address, 2) << " | ";
- Analysis.printInstruction(InstrMeta, outs());
- outs() << " \n";
-
- if (PrintGraphs)
- Graph.printToDOT(Analysis, outs());
+ if (!Summarize) {
+ outs() << "-----------------------------------------------------\n";
+ printInstructionInformation(Analysis, InstrMeta, Graph, ProtectionStatus);
+ }
if (IgnoreDWARFFlag) {
if (CFIProtected)
@@ -88,22 +159,28 @@ void printIndirectCFInstructions(FileAnalysis &Analysis,
exit(EXIT_FAILURE);
}
- const auto &LineInfo =
- InliningInfo->getFrame(InliningInfo->getNumberOfFrames() - 1);
+ const auto &LineInfo = InliningInfo->getFrame(0);
// Print the inlining symbolisation of this instruction.
- for (uint32_t i = 0; i < InliningInfo->getNumberOfFrames(); ++i) {
- const auto &Line = InliningInfo->getFrame(i);
- outs() << " " << format_hex(Address, 2) << " = " << Line.FileName << ":"
- << Line.Line << ":" << Line.Column << " (" << Line.FunctionName
- << ")\n";
+ if (!Summarize) {
+ for (uint32_t i = 0; i < InliningInfo->getNumberOfFrames(); ++i) {
+ const auto &Line = InliningInfo->getFrame(i);
+ outs() << " " << format_hex(Address, 2) << " = " << Line.FileName
+ << ":" << Line.Line << ":" << Line.Column << " ("
+ << Line.FunctionName << ")\n";
+ }
}
if (!SpecialCaseList) {
- if (CFIProtected)
+ if (CFIProtected) {
+ if (PrintBlameContextAll && !Summarize)
+ printBlameContext(LineInfo, PrintBlameContextAll);
ExpectedProtected++;
- else
+ } else {
+ if (PrintBlameContext && !Summarize)
+ printBlameContext(LineInfo, PrintBlameContext);
UnexpectedUnprotected++;
+ }
continue;
}
@@ -118,25 +195,20 @@ void printIndirectCFInstructions(FileAnalysis &Analysis,
}
if (BlameLine) {
- outs() << "Blacklist Match: " << BlacklistFilename << ":" << BlameLine
- << "\n";
BlameCounter[BlameLine]++;
- if (CFIProtected) {
+ if (CFIProtected)
UnexpectedProtected++;
- outs() << "====> Unexpected Protected\n";
- } else {
+ else
ExpectedUnprotected++;
- outs() << "====> Expected Unprotected\n";
- }
} else {
- if (CFIProtected) {
+ if (CFIProtected)
ExpectedProtected++;
- outs() << "====> Expected Protected\n";
- } else {
+ else
UnexpectedUnprotected++;
- outs() << "====> Unexpected Unprotected\n";
- }
}
+
+ if (!Summarize)
+ printInstructionStatus(BlameLine, CFIProtected, LineInfo);
}
uint64_t IndirectCFInstructions = ExpectedProtected + UnexpectedProtected +
@@ -147,11 +219,12 @@ void printIndirectCFInstructions(FileAnalysis &Analysis,
return;
}
- outs() << formatv("Expected Protected: {0} ({1:P})\n"
- "Unexpected Protected: {2} ({3:P})\n"
- "Expected Unprotected: {4} ({5:P})\n"
- "Unexpected Unprotected (BAD): {6} ({7:P})\n",
- ExpectedProtected,
+ outs() << formatv("\nTotal Indirect CF Instructions: {0}\n"
+ "Expected Protected: {1} ({2:P})\n"
+ "Unexpected Protected: {3} ({4:P})\n"
+ "Expected Unprotected: {5} ({6:P})\n"
+ "Unexpected Unprotected (BAD): {7} ({8:P})\n",
+ IndirectCFInstructions, ExpectedProtected,
((double)ExpectedProtected) / IndirectCFInstructions,
UnexpectedProtected,
((double)UnexpectedProtected) / IndirectCFInstructions,
@@ -163,7 +236,7 @@ void printIndirectCFInstructions(FileAnalysis &Analysis,
if (!SpecialCaseList)
return;
- outs() << "Blacklist Results:\n";
+ outs() << "\nBlacklist Results:\n";
for (const auto &KV : BlameCounter) {
outs() << " " << BlacklistFilename << ":" << KV.first << " affects "
<< KV.second << " indirect CF instructions.\n";
@@ -183,6 +256,9 @@ int main(int argc, char **argv) {
InitializeAllAsmParsers();
InitializeAllDisassemblers();
+ if (PrintBlameContextAll && !PrintBlameContext)
+ PrintBlameContext.setValue(PrintBlameContextAll);
+
std::unique_ptr<SpecialCaseList> SpecialCaseList;
if (BlacklistFilename != "-") {
std::string Error;
OpenPOWER on IntegriCloud