summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-cfi-verify/llvm-cfi-verify.cpp
diff options
context:
space:
mode:
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