//===-- llvm-bcanalyzer.cpp - Bitcode Analyzer --------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This tool may be invoked in the following manner: // llvm-bcanalyzer [options] - Read LLVM bitcode from stdin // llvm-bcanalyzer [options] x.bc - Read LLVM bitcode from the x.bc file // // Options: // --help - Output information about command line switches // --dump - Dump low-level bitcode structure in readable format // // This tool provides analytical information about a bitcode file. It is // intended as an aid to developers of bitcode reading and writing software. It // produces on std::out a summary of the bitcode file that shows various // statistics about the contents of the file. By default this information is // detailed and contains information about individual bitcode blocks and the // functions in the module. // The tool is also able to print a bitcode file in a straight forward text // format that shows the containment and relationships of the information in // the bitcode file (-dump option). // //===----------------------------------------------------------------------===// #include "llvm/ADT/Optional.h" #include "llvm/Bitcode/BitcodeAnalyzer.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Error.h" #include "llvm/Support/InitLLVM.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/raw_ostream.h" #include using namespace llvm; static cl::opt InputFilename(cl::Positional, cl::desc(""), cl::init("-")); static cl::opt Dump("dump", cl::desc("Dump low level bitcode trace")); //===----------------------------------------------------------------------===// // Bitcode specific analysis. //===----------------------------------------------------------------------===// static cl::opt NoHistogram("disable-histogram", cl::desc("Do not print per-code histogram")); static cl::opt NonSymbolic("non-symbolic", cl::desc("Emit numeric info in dump even if" " symbolic info is available")); static cl::opt BlockInfoFilename("block-info", cl::desc("Use the BLOCK_INFO from the given file")); static cl::opt ShowBinaryBlobs("show-binary-blobs", cl::desc("Print binary blobs using hex escapes")); static cl::opt CheckHash( "check-hash", cl::desc("Check module hash using the argument as a string table")); static Error reportError(StringRef Message) { return createStringError(std::errc::illegal_byte_sequence, Message.data()); } static Expected> openBitcodeFile(StringRef Path) { // Read the input file. Expected> MemBufOrErr = errorOrToExpected(MemoryBuffer::getFileOrSTDIN(Path)); if (Error E = MemBufOrErr.takeError()) return std::move(E); std::unique_ptr MemBuf = std::move(*MemBufOrErr); if (MemBuf->getBufferSize() & 3) return reportError( "Bitcode stream should be a multiple of 4 bytes in length"); return std::move(MemBuf); } int main(int argc, char **argv) { InitLLVM X(argc, argv); cl::ParseCommandLineOptions(argc, argv, "llvm-bcanalyzer file analyzer\n"); ExitOnError ExitOnErr("llvm-bcanalyzer: "); std::unique_ptr MB = ExitOnErr(openBitcodeFile(InputFilename)); std::unique_ptr BlockInfoMB = nullptr; if (!BlockInfoFilename.empty()) BlockInfoMB = ExitOnErr(openBitcodeFile(BlockInfoFilename)); BitcodeAnalyzer BA(MB->getBuffer(), BlockInfoMB ? Optional(BlockInfoMB->getBuffer()) : None); BCDumpOptions O(outs()); O.Histogram = !NoHistogram; O.Symbolic = !NonSymbolic; O.ShowBinaryBlobs = ShowBinaryBlobs; ExitOnErr( BA.analyze(O, CheckHash.empty() ? None : Optional(CheckHash))); if (Dump) outs() << "\n\n"; BA.printStats(O, StringRef(InputFilename.getValue())); return 0; }