[cfi-verify] Adds blacklist blame behaviour to cfi-verify.
authorMitch Phillips <mitchphillips@outlook.com>
Thu, 9 Nov 2017 00:18:31 +0000 (00:18 +0000)
committerMitch Phillips <mitchphillips@outlook.com>
Thu, 9 Nov 2017 00:18:31 +0000 (00:18 +0000)
Adds the blacklist behaviour to llvm-cfi-verify. Now will calculate which lines caused expected failures in the blacklist and reports the number of affected indirect CF instructions for each blacklist entry.

Also moved DWARF checking after instruction analysis to improve performance significantly - unrolling the inlining stack is expensive.

Reviewers: vlad.tsyrklevich

Subscribers: aprantl, pcc, kcc, llvm-commits

Differential Revision: https://reviews.llvm.org/D39750

llvm-svn: 317743

llvm/test/tools/llvm-cfi-verify/X86/blacklist-expected-unprotected.s
llvm/test/tools/llvm-cfi-verify/X86/blacklist-match-fun.s
llvm/test/tools/llvm-cfi-verify/X86/blacklist-unexpected-protected.s
llvm/tools/llvm-cfi-verify/lib/FileAnalysis.cpp
llvm/tools/llvm-cfi-verify/llvm-cfi-verify.cpp

index fbcfcc2..c7a3daa 100644 (file)
@@ -5,7 +5,7 @@
 
 # CHECK-LABEL: U
 # CHECK-NEXT: tiny.cc:11
-# CHECK-NEXT: BLACKLIST MATCH, 'src'
+# CHECK-NEXT: {{^Blacklist Match:.*blacklist\.txt:1$}}
 # CHECK-NEXT: ====> Expected Unprotected
 
 # CHECK: Expected Protected: 0 (0.00%)
index 3ea8293..f46fb92 100644 (file)
@@ -5,7 +5,7 @@
 
 # CHECK-LABEL: U
 # CHECK-NEXT: tiny.cc:11
-# CHECK-NEXT: BLACKLIST MATCH, 'fun'
+# CHECK-NEXT: {{^Blacklist Match:.*blacklist\.txt:1$}}
 # CHECK-NEXT: ====> Expected Unprotected
 
 # CHECK: Expected Protected: 0 (0.00%)
index c6ddf2b..0fd4124 100644 (file)
@@ -5,7 +5,7 @@
 
 # CHECK-LABEL: P
 # CHECK-NEXT: tiny.cc:11
-# CHECK-NEXT: BLACKLIST MATCH, 'src'
+# CHECK-NEXT: {{^Blacklist Match:.*blacklist\.txt:1$}}
 # CHECK-NEXT: ====> Unexpected Protected
 
 # CHECK: Expected Protected: 0 (0.00%)
index 0d4e1f4..863bbfb 100644 (file)
@@ -370,21 +370,6 @@ void FileAnalysis::parseSectionContents(ArrayRef<uint8_t> SectionBytes,
     InstrMeta.InstructionSize = InstructionSize;
     InstrMeta.Valid = ValidInstruction;
 
-    // Check if this instruction exists in the range of the DWARF metadata.
-    if (!IgnoreDWARFFlag) {
-      auto LineInfo =
-          Symbolizer->symbolizeCode(Object->getFileName(), VMAddress);
-      if (!LineInfo) {
-        handleAllErrors(LineInfo.takeError(), [](const ErrorInfoBase &E) {
-          errs() << "Symbolizer failed to get line: " << E.message() << "\n";
-        });
-        continue;
-      }
-
-      if (LineInfo->FileName == "<invalid>")
-        continue;
-    }
-
     addInstruction(InstrMeta);
 
     if (!ValidInstruction)
@@ -406,6 +391,21 @@ void FileAnalysis::parseSectionContents(ArrayRef<uint8_t> SectionBytes,
     if (!usesRegisterOperand(InstrMeta))
       continue;
 
+    // Check if this instruction exists in the range of the DWARF metadata.
+    if (!IgnoreDWARFFlag) {
+      auto LineInfo =
+          Symbolizer->symbolizeCode(Object->getFileName(), VMAddress);
+      if (!LineInfo) {
+        handleAllErrors(LineInfo.takeError(), [](const ErrorInfoBase &E) {
+          errs() << "Symbolizer failed to get line: " << E.message() << "\n";
+        });
+        continue;
+      }
+
+      if (LineInfo->FileName == "<invalid>")
+        continue;
+    }
+
     IndirectInstructions.insert(VMAddress);
   }
 }
index 3b4a5c1..01f0315 100644 (file)
@@ -47,6 +47,7 @@ void printIndirectCFInstructions(FileAnalysis &Analysis,
   uint64_t UnexpectedUnprotected = 0;
 
   symbolize::LLVMSymbolizer &Symbolizer = Analysis.getSymbolizer();
+  std::map<unsigned, uint64_t> BlameCounter;
 
   for (uint64_t Address : Analysis.getIndirectInstructions()) {
     const auto &InstrMeta = Analysis.getInstructionOrDie(Address);
@@ -97,20 +98,20 @@ void printIndirectCFInstructions(FileAnalysis &Analysis,
       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;
+    unsigned BlameLine = 0;
+    for (auto &K : {"cfi-icall", "cfi-vcall"}) {
+      if (!BlameLine)
+        BlameLine =
+            SpecialCaseList->inSectionBlame(K, "src", LineInfo.FileName);
+      if (!BlameLine)
+        BlameLine =
+            SpecialCaseList->inSectionBlame(K, "fun", LineInfo.FunctionName);
     }
 
-    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 (BlameLine) {
+      outs() << "Blacklist Match: " << BlacklistFilename << ":" << BlameLine
+             << "\n";
+      BlameCounter[BlameLine]++;
       if (CFIProtected) {
         UnexpectedProtected++;
         outs() << "====> Unexpected Protected\n";
@@ -149,6 +150,15 @@ void printIndirectCFInstructions(FileAnalysis &Analysis,
                     ((double)ExpectedUnprotected) / IndirectCFInstructions,
                     UnexpectedUnprotected,
                     ((double)UnexpectedUnprotected) / IndirectCFInstructions);
+
+  if (!SpecialCaseList)
+    return;
+
+  outs() << "Blacklist Results:\n";
+  for (const auto &KV : BlameCounter) {
+    outs() << "  " << BlacklistFilename << ":" << KV.first << " affects "
+           << KV.second << " indirect CF instructions.\n";
+  }
 }
 
 int main(int argc, char **argv) {