llvm-dis.cpp revision ec080467f5b322441055de1f6cd4f08edc23d7df
11dd27b157bbe7d9e44fa72abbc8b0f08eba804ecChris Lattner//===-- llvm-dis.cpp - The low-level LLVM disassembler --------------------===//
23da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman//
37c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell//                     The LLVM Compiler Infrastructure
47c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell//
521c62da287237d39d0d95004881ea4baae3be6daChris Lattner// This file is distributed under the University of Illinois Open Source
621c62da287237d39d0d95004881ea4baae3be6daChris Lattner// License. See LICENSE.TXT for details.
73da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman//
87c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell//===----------------------------------------------------------------------===//
9009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//
10009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// This utility may be invoked in the following manner:
11a99be51bf5cdac1438069d4b01766c47704961c8Gabor Greif//  llvm-dis [options]      - Read LLVM bitcode from stdin, write asm to stdout
12a99be51bf5cdac1438069d4b01766c47704961c8Gabor Greif//  llvm-dis [options] x.bc - Read LLVM bitcode from the x.bc file, write asm
13ad0bf0fc0cead2c714d6a0e164d3bdb2864eb8e1Misha Brukman//                            to the x.ll file.
149bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner//  Options:
159bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner//      --help   - Output information about command line switches
16009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//
171d7b50b4f823012dc283e46c2bd8036d32b402f4Chris Lattner//===----------------------------------------------------------------------===//
18009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
198b477ed579794ba6d76915d56b3f448a7dd20120Owen Anderson#include "llvm/LLVMContext.h"
20009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner#include "llvm/Module.h"
210179450064562c765baa70755ef402c860e1134cChris Lattner#include "llvm/PassManager.h"
22b3ca3622bbb75f939173236f4e82e3e9b345630aChris Lattner#include "llvm/Bitcode/ReaderWriter.h"
230179450064562c765baa70755ef402c860e1134cChris Lattner#include "llvm/Assembly/PrintModulePass.h"
24551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#include "llvm/Support/CommandLine.h"
25c30598bc3ad792eb8cc75b188eb872a28c62ab71Chris Lattner#include "llvm/Support/ManagedStatic.h"
26c453f76e2b4d7fd1e042b5b6d4c20556779186dfChris Lattner#include "llvm/Support/MemoryBuffer.h"
27cc14d25dd99e891c586bd56aa41796abbe4ac3d8Chris Lattner#include "llvm/Support/PrettyStackTrace.h"
283b0da26e202cbbeb22508231f4278bda8e995391Daniel Dunbar#include "llvm/Support/raw_ostream.h"
29bed85ff010b95923646ed4e187a5d432cedf67daChris Lattner#include "llvm/System/Signals.h"
300179450064562c765baa70755ef402c860e1134cChris Lattner#include <memory>
31d0fde30ce850b78371fd1386338350591f9ff494Brian Gaekeusing namespace llvm;
32d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke
33c7a0985995631025fbe9a4fe9fc435c3ba7387e4Chris Lattnerstatic cl::opt<std::string>
34a99be51bf5cdac1438069d4b01766c47704961c8Gabor GreifInputFilename(cl::Positional, cl::desc("<input bitcode>"), cl::init("-"));
355ff62e90d0bc321206023897edc1e2691cb0fbb6Chris Lattner
36c7a0985995631025fbe9a4fe9fc435c3ba7387e4Chris Lattnerstatic cl::opt<std::string>
373da94aec4d429b2ba0f65fa040c33650cade196bMisha BrukmanOutputFilename("o", cl::desc("Override output filename"),
385ff62e90d0bc321206023897edc1e2691cb0fbb6Chris Lattner               cl::value_desc("filename"));
395ff62e90d0bc321206023897edc1e2691cb0fbb6Chris Lattner
405ff62e90d0bc321206023897edc1e2691cb0fbb6Chris Lattnerstatic cl::opt<bool>
41baa26395ccf17fc988bb9cf62d6659ca8415ece9Dan GohmanForce("f", cl::desc("Enable binary output on terminals"));
425ff62e90d0bc321206023897edc1e2691cb0fbb6Chris Lattner
434d544cd646440fb99131206d6f074fa32dc308dcChris Lattnerstatic cl::opt<bool>
444d544cd646440fb99131206d6f074fa32dc308dcChris LattnerDontPrint("disable-output", cl::desc("Don't output the .ll file"), cl::Hidden);
454d544cd646440fb99131206d6f074fa32dc308dcChris Lattner
468f367bd3c0f56b7b318c46cee04f77735f617777Chris Lattnerint main(int argc, char **argv) {
47cc14d25dd99e891c586bd56aa41796abbe4ac3d8Chris Lattner  // Print a stack trace if we signal out.
48cc14d25dd99e891c586bd56aa41796abbe4ac3d8Chris Lattner  sys::PrintStackTraceOnErrorSignal();
49cc14d25dd99e891c586bd56aa41796abbe4ac3d8Chris Lattner  PrettyStackTraceProgram X(argc, argv);
50cc14d25dd99e891c586bd56aa41796abbe4ac3d8Chris Lattner
510d7c695c74ae6d5f68cc07378c17491915e607d3Owen Anderson  LLVMContext &Context = getGlobalContext();
52cc14d25dd99e891c586bd56aa41796abbe4ac3d8Chris Lattner  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.
5317e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner
5417e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner
5517e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner  cl::ParseCommandLineOptions(argc, argv, "llvm .bc -> .ll disassembler\n");
56009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
5717e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner  std::string ErrorMessage;
5817e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner  std::auto_ptr<Module> M;
5917e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner
6017e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner  if (MemoryBuffer *Buffer
6117e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner         = MemoryBuffer::getFileOrSTDIN(InputFilename, &ErrorMessage)) {
6217e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner    M.reset(ParseBitcodeFile(Buffer, Context, &ErrorMessage));
6317e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner    delete Buffer;
6417e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner  }
65c453f76e2b4d7fd1e042b5b6d4c20556779186dfChris Lattner
6617e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner  if (M.get() == 0) {
6717e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner    errs() << argv[0] << ": ";
6817e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner    if (ErrorMessage.size())
6917e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner      errs() << ErrorMessage << "\n";
7017e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner    else
7117e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner      errs() << "bitcode didn't read correctly.\n";
7217e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner    return 1;
7317e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner  }
7417e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner
7517e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner  // Just use stdout.  We won't actually print anything on it.
7617e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner  if (DontPrint)
7717e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner    OutputFilename = "-";
7817e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner
7917e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner  if (OutputFilename.empty()) { // Unspecified output, infer it.
8017e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner    if (InputFilename == "-") {
8117e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner      OutputFilename = "-";
821ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer    } else {
8317e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner      const std::string &IFN = InputFilename;
8417e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner      int Len = IFN.length();
8517e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner      // If the source ends in .bc, strip it off.
8617e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner      if (IFN[Len-3] == '.' && IFN[Len-2] == 'b' && IFN[Len-1] == 'c')
8717e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner        OutputFilename = std::string(IFN.begin(), IFN.end()-3)+".ll";
8817e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner      else
8917e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner        OutputFilename = IFN+".ll";
901ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer    }
9117e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner  }
92ec080467f5b322441055de1f6cd4f08edc23d7dfDan Gohman
93ec080467f5b322441055de1f6cd4f08edc23d7dfDan Gohman  // Make sure that the Out file gets unlinked from the disk if we get a
94ec080467f5b322441055de1f6cd4f08edc23d7dfDan Gohman  // SIGINT.
95ec080467f5b322441055de1f6cd4f08edc23d7dfDan Gohman  if (OutputFilename != "-")
96ec080467f5b322441055de1f6cd4f08edc23d7dfDan Gohman    sys::RemoveFileOnSignal(sys::Path(OutputFilename));
97ec080467f5b322441055de1f6cd4f08edc23d7dfDan Gohman
9817e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner  std::string ErrorInfo;
9917e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner  std::auto_ptr<raw_fd_ostream>
10017e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner  Out(new raw_fd_ostream(OutputFilename.c_str(), ErrorInfo,
10117e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner                         raw_fd_ostream::F_Binary));
10217e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner  if (!ErrorInfo.empty()) {
10317e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner    errs() << ErrorInfo << '\n';
10417e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner    return 1;
10517e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner  }
1068f367bd3c0f56b7b318c46cee04f77735f617777Chris Lattner
10717e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner  // All that llvm-dis does is write the assembly to a file.
10817e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner  if (!DontPrint) {
10917e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner    PassManager Passes;
11017e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner    Passes.add(createPrintModulePass(Out.get()));
11117e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner    Passes.run(*M.get());
11293c26685bf80f38c4b23d0ed9b0735d6dbb9c1d3Chris Lattner  }
113c30598bc3ad792eb8cc75b188eb872a28c62ab71Chris Lattner
11417e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner  return 0;
115009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner}
1169ddc86c6e51617d1170eed07a4320edf6679f655Sumant Kowshik
117