summaryrefslogtreecommitdiff
path: root/tools/llvm-cfi-verify/llvm-cfi-verify.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/llvm-cfi-verify/llvm-cfi-verify.cpp')
-rw-r--r--tools/llvm-cfi-verify/llvm-cfi-verify.cpp135
1 files changed, 110 insertions, 25 deletions
diff --git a/tools/llvm-cfi-verify/llvm-cfi-verify.cpp b/tools/llvm-cfi-verify/llvm-cfi-verify.cpp
index d4a46fcc226b..3b4a5c155d04 100644
--- a/tools/llvm-cfi-verify/llvm-cfi-verify.cpp
+++ b/tools/llvm-cfi-verify/llvm-cfi-verify.cpp
@@ -23,6 +23,7 @@
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/FormatVariadic.h"
+#include "llvm/Support/SpecialCaseList.h"
#include <cstdlib>
@@ -32,48 +33,122 @@ using namespace llvm::cfi_verify;
cl::opt<std::string> InputFilename(cl::Positional, cl::desc("<input file>"),
cl::Required);
+cl::opt<std::string> BlacklistFilename(cl::Positional,
+ cl::desc("[blacklist file]"),
+ cl::init("-"));
ExitOnError ExitOnErr;
-void printIndirectCFInstructions(FileAnalysis &Analysis) {
- uint64_t ProtectedCount = 0;
- uint64_t UnprotectedCount = 0;
+void printIndirectCFInstructions(FileAnalysis &Analysis,
+ const SpecialCaseList *SpecialCaseList) {
+ uint64_t ExpectedProtected = 0;
+ uint64_t UnexpectedProtected = 0;
+ uint64_t ExpectedUnprotected = 0;
+ uint64_t UnexpectedUnprotected = 0;
+
+ symbolize::LLVMSymbolizer &Symbolizer = Analysis.getSymbolizer();
for (uint64_t Address : Analysis.getIndirectInstructions()) {
const auto &InstrMeta = Analysis.getInstructionOrDie(Address);
- if (Analysis.isIndirectInstructionCFIProtected(Address)) {
+ bool CFIProtected = Analysis.isIndirectInstructionCFIProtected(Address);
+
+ if (CFIProtected)
outs() << "P ";
- ProtectedCount++;
- } else {
+ else
outs() << "U ";
- UnprotectedCount++;
- }
outs() << format_hex(Address, 2) << " | "
<< Analysis.getMCInstrInfo()->getName(
InstrMeta.Instruction.getOpcode())
- << " ";
- outs() << "\n";
-
- if (Analysis.hasLineTableInfo()) {
- for (const auto &LineKV : Analysis.getLineInfoForAddressRange(Address)) {
- outs() << " " << format_hex(LineKV.first, 2) << " = "
- << LineKV.second.FileName << ":" << LineKV.second.Line << ":"
- << LineKV.second.Column << " (" << LineKV.second.FunctionName
- << ")\n";
+ << " \n";
+
+ if (IgnoreDWARFFlag) {
+ if (CFIProtected)
+ ExpectedProtected++;
+ else
+ UnexpectedUnprotected++;
+ continue;
+ }
+
+ auto InliningInfo = Symbolizer.symbolizeInlinedCode(InputFilename, Address);
+ if (!InliningInfo || InliningInfo->getNumberOfFrames() == 0) {
+ errs() << "Failed to symbolise " << format_hex(Address, 2)
+ << " with line tables from " << InputFilename << "\n";
+ exit(EXIT_FAILURE);
+ }
+
+ const auto &LineInfo =
+ InliningInfo->getFrame(InliningInfo->getNumberOfFrames() - 1);
+
+ // 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 (!SpecialCaseList) {
+ if (CFIProtected)
+ ExpectedProtected++;
+ else
+ UnexpectedUnprotected++;
+ continue;
+ }
+
+ bool MatchesBlacklistRule = false;
+ if (SpecialCaseList->inSection("cfi-icall", "src", LineInfo.FileName) ||
+ SpecialCaseList->inSection("cfi-vcall", "src", LineInfo.FileName)) {
+ outs() << "BLACKLIST MATCH, 'src'\n";
+ MatchesBlacklistRule = true;
+ }
+
+ if (SpecialCaseList->inSection("cfi-icall", "fun", LineInfo.FunctionName) ||
+ SpecialCaseList->inSection("cfi-vcall", "fun", LineInfo.FunctionName)) {
+ outs() << "BLACKLIST MATCH, 'fun'\n";
+ MatchesBlacklistRule = true;
+ }
+
+ if (MatchesBlacklistRule) {
+ if (CFIProtected) {
+ UnexpectedProtected++;
+ outs() << "====> Unexpected Protected\n";
+ } else {
+ ExpectedUnprotected++;
+ outs() << "====> Expected Unprotected\n";
+ }
+ } else {
+ if (CFIProtected) {
+ ExpectedProtected++;
+ outs() << "====> Expected Protected\n";
+ } else {
+ UnexpectedUnprotected++;
+ outs() << "====> Unexpected Unprotected\n";
}
}
}
- if (ProtectedCount || UnprotectedCount)
- outs() << formatv(
- "Unprotected: {0} ({1:P}), Protected: {2} ({3:P})\n", UnprotectedCount,
- (((double)UnprotectedCount) / (UnprotectedCount + ProtectedCount)),
- ProtectedCount,
- (((double)ProtectedCount) / (UnprotectedCount + ProtectedCount)));
- else
+ uint64_t IndirectCFInstructions = ExpectedProtected + UnexpectedProtected +
+ ExpectedUnprotected + UnexpectedUnprotected;
+
+ if (IndirectCFInstructions == 0) {
outs() << "No indirect CF instructions found.\n";
+ 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,
+ ((double)ExpectedProtected) / IndirectCFInstructions,
+ UnexpectedProtected,
+ ((double)UnexpectedProtected) / IndirectCFInstructions,
+ ExpectedUnprotected,
+ ((double)ExpectedUnprotected) / IndirectCFInstructions,
+ UnexpectedUnprotected,
+ ((double)UnexpectedUnprotected) / IndirectCFInstructions);
}
int main(int argc, char **argv) {
@@ -89,8 +164,18 @@ int main(int argc, char **argv) {
InitializeAllAsmParsers();
InitializeAllDisassemblers();
+ std::unique_ptr<SpecialCaseList> SpecialCaseList;
+ if (BlacklistFilename != "-") {
+ std::string Error;
+ SpecialCaseList = SpecialCaseList::create({BlacklistFilename}, Error);
+ if (!SpecialCaseList) {
+ errs() << "Failed to get blacklist: " << Error << "\n";
+ exit(EXIT_FAILURE);
+ }
+ }
+
FileAnalysis Analysis = ExitOnErr(FileAnalysis::Create(InputFilename));
- printIndirectCFInstructions(Analysis);
+ printIndirectCFInstructions(Analysis, SpecialCaseList.get());
return EXIT_SUCCESS;
}