diff options
Diffstat (limited to 'llvm/tools/llvm-cfi-verify/llvm-cfi-verify.cpp')
| -rw-r--r-- | llvm/tools/llvm-cfi-verify/llvm-cfi-verify.cpp | 152 | 
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; | 

