llvm-bcanalyzer.cpp revision 360784
1//===-- llvm-bcanalyzer.cpp - Bitcode Analyzer --------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This tool may be invoked in the following manner:
10//  llvm-bcanalyzer [options]      - Read LLVM bitcode from stdin
11//  llvm-bcanalyzer [options] x.bc - Read LLVM bitcode from the x.bc file
12//
13//  Options:
14//      --help      - Output information about command line switches
15//      --dump      - Dump low-level bitcode structure in readable format
16//
17// This tool provides analytical information about a bitcode file. It is
18// intended as an aid to developers of bitcode reading and writing software. It
19// produces on std::out a summary of the bitcode file that shows various
20// statistics about the contents of the file. By default this information is
21// detailed and contains information about individual bitcode blocks and the
22// functions in the module.
23// The tool is also able to print a bitcode file in a straight forward text
24// format that shows the containment and relationships of the information in
25// the bitcode file (-dump option).
26//
27//===----------------------------------------------------------------------===//
28
29#include "llvm/ADT/Optional.h"
30#include "llvm/Bitcode/BitcodeAnalyzer.h"
31#include "llvm/Support/CommandLine.h"
32#include "llvm/Support/Error.h"
33#include "llvm/Support/InitLLVM.h"
34#include "llvm/Support/MemoryBuffer.h"
35#include "llvm/Support/raw_ostream.h"
36#include <memory>
37using namespace llvm;
38
39static cl::opt<std::string>
40    InputFilename(cl::Positional, cl::desc("<input bitcode>"), cl::init("-"));
41
42static cl::opt<bool> Dump("dump", cl::desc("Dump low level bitcode trace"));
43
44//===----------------------------------------------------------------------===//
45// Bitcode specific analysis.
46//===----------------------------------------------------------------------===//
47
48static cl::opt<bool> NoHistogram("disable-histogram",
49                                 cl::desc("Do not print per-code histogram"));
50
51static cl::opt<bool> NonSymbolic("non-symbolic",
52                                 cl::desc("Emit numeric info in dump even if"
53                                          " symbolic info is available"));
54
55static cl::opt<std::string>
56    BlockInfoFilename("block-info",
57                      cl::desc("Use the BLOCK_INFO from the given file"));
58
59static cl::opt<bool>
60    ShowBinaryBlobs("show-binary-blobs",
61                    cl::desc("Print binary blobs using hex escapes"));
62
63static cl::opt<std::string> CheckHash(
64    "check-hash",
65    cl::desc("Check module hash using the argument as a string table"));
66
67static Error reportError(StringRef Message) {
68  return createStringError(std::errc::illegal_byte_sequence, Message.data());
69}
70
71static Expected<std::unique_ptr<MemoryBuffer>> openBitcodeFile(StringRef Path) {
72  // Read the input file.
73  Expected<std::unique_ptr<MemoryBuffer>> MemBufOrErr =
74      errorOrToExpected(MemoryBuffer::getFileOrSTDIN(Path));
75  if (Error E = MemBufOrErr.takeError())
76    return std::move(E);
77
78  std::unique_ptr<MemoryBuffer> MemBuf = std::move(*MemBufOrErr);
79
80  if (MemBuf->getBufferSize() & 3)
81    return reportError(
82        "Bitcode stream should be a multiple of 4 bytes in length");
83  return std::move(MemBuf);
84}
85
86int main(int argc, char **argv) {
87  InitLLVM X(argc, argv);
88  cl::ParseCommandLineOptions(argc, argv, "llvm-bcanalyzer file analyzer\n");
89  ExitOnError ExitOnErr("llvm-bcanalyzer: ");
90
91  std::unique_ptr<MemoryBuffer> MB = ExitOnErr(openBitcodeFile(InputFilename));
92  std::unique_ptr<MemoryBuffer> BlockInfoMB = nullptr;
93  if (!BlockInfoFilename.empty())
94    BlockInfoMB = ExitOnErr(openBitcodeFile(BlockInfoFilename));
95
96  BitcodeAnalyzer BA(MB->getBuffer(),
97                     BlockInfoMB ? Optional<StringRef>(BlockInfoMB->getBuffer())
98                                 : None);
99
100  BCDumpOptions O(outs());
101  O.Histogram = !NoHistogram;
102  O.Symbolic = !NonSymbolic;
103  O.ShowBinaryBlobs = ShowBinaryBlobs;
104
105  ExitOnErr(BA.analyze(
106      Dump ? Optional<BCDumpOptions>(O) : Optional<BCDumpOptions>(None),
107      CheckHash.empty() ? None : Optional<StringRef>(CheckHash)));
108
109  if (Dump)
110    outs() << "\n\n";
111
112  BA.printStats(O, StringRef(InputFilename.getValue()));
113  return 0;
114}
115