llvm-dis.cpp revision 195340
1193323Sed//===-- llvm-dis.cpp - The low-level LLVM disassembler --------------------===// 2193323Sed// 3193323Sed// The LLVM Compiler Infrastructure 4193323Sed// 5193323Sed// This file is distributed under the University of Illinois Open Source 6193323Sed// License. See LICENSE.TXT for details. 7193323Sed// 8193323Sed//===----------------------------------------------------------------------===// 9193323Sed// 10193323Sed// This utility may be invoked in the following manner: 11193323Sed// llvm-dis [options] - Read LLVM bitcode from stdin, write asm to stdout 12193323Sed// llvm-dis [options] x.bc - Read LLVM bitcode from the x.bc file, write asm 13193323Sed// to the x.ll file. 14193323Sed// Options: 15193323Sed// --help - Output information about command line switches 16193323Sed// 17193323Sed//===----------------------------------------------------------------------===// 18193323Sed 19195340Sed#include "llvm/LLVMContext.h" 20193323Sed#include "llvm/Module.h" 21193323Sed#include "llvm/PassManager.h" 22193323Sed#include "llvm/Bitcode/ReaderWriter.h" 23193323Sed#include "llvm/Assembly/PrintModulePass.h" 24193323Sed#include "llvm/Support/CommandLine.h" 25193323Sed#include "llvm/Support/ManagedStatic.h" 26193323Sed#include "llvm/Support/MemoryBuffer.h" 27193323Sed#include "llvm/Support/PrettyStackTrace.h" 28193323Sed#include "llvm/Support/Streams.h" 29193323Sed#include "llvm/Support/raw_ostream.h" 30193323Sed#include "llvm/System/Signals.h" 31193323Sed#include <iostream> 32193323Sed#include <fstream> 33193323Sed#include <memory> 34193323Sedusing namespace llvm; 35193323Sed 36193323Sedstatic cl::opt<std::string> 37193323SedInputFilename(cl::Positional, cl::desc("<input bitcode>"), cl::init("-")); 38193323Sed 39193323Sedstatic cl::opt<std::string> 40193323SedOutputFilename("o", cl::desc("Override output filename"), 41193323Sed cl::value_desc("filename")); 42193323Sed 43193323Sedstatic cl::opt<bool> 44193323SedForce("f", cl::desc("Overwrite output files")); 45193323Sed 46193323Sedstatic cl::opt<bool> 47193323SedDontPrint("disable-output", cl::desc("Don't output the .ll file"), cl::Hidden); 48193323Sed 49193323Sedint main(int argc, char **argv) { 50193323Sed // Print a stack trace if we signal out. 51193323Sed sys::PrintStackTraceOnErrorSignal(); 52193323Sed PrettyStackTraceProgram X(argc, argv); 53193323Sed 54195340Sed LLVMContext Context; 55193323Sed llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. 56193323Sed try { 57193323Sed cl::ParseCommandLineOptions(argc, argv, "llvm .bc -> .ll disassembler\n"); 58193323Sed 59193323Sed std::ostream *Out = &std::cout; // Default to printing to stdout. 60193323Sed std::string ErrorMessage; 61193323Sed 62193323Sed std::auto_ptr<Module> M; 63193323Sed 64193323Sed if (MemoryBuffer *Buffer 65193323Sed = MemoryBuffer::getFileOrSTDIN(InputFilename, &ErrorMessage)) { 66195340Sed M.reset(ParseBitcodeFile(Buffer, Context, &ErrorMessage)); 67193323Sed delete Buffer; 68193323Sed } 69193323Sed 70193323Sed if (M.get() == 0) { 71193323Sed cerr << argv[0] << ": "; 72193323Sed if (ErrorMessage.size()) 73193323Sed cerr << ErrorMessage << "\n"; 74193323Sed else 75193323Sed cerr << "bitcode didn't read correctly.\n"; 76193323Sed return 1; 77193323Sed } 78193323Sed 79193323Sed if (DontPrint) { 80193323Sed // Just use stdout. We won't actually print anything on it. 81193323Sed } else if (OutputFilename != "") { // Specified an output filename? 82193323Sed if (OutputFilename != "-") { // Not stdout? 83193323Sed if (!Force && std::ifstream(OutputFilename.c_str())) { 84193323Sed // If force is not specified, make sure not to overwrite a file! 85193323Sed cerr << argv[0] << ": error opening '" << OutputFilename 86193323Sed << "': file exists! Sending to standard output.\n"; 87193323Sed } else { 88193323Sed Out = new std::ofstream(OutputFilename.c_str()); 89193323Sed } 90193323Sed } 91193323Sed } else { 92193323Sed if (InputFilename == "-") { 93193323Sed OutputFilename = "-"; 94193323Sed } else { 95193323Sed std::string IFN = InputFilename; 96193323Sed int Len = IFN.length(); 97193323Sed if (IFN[Len-3] == '.' && IFN[Len-2] == 'b' && IFN[Len-1] == 'c') { 98193323Sed // Source ends in .bc 99193323Sed OutputFilename = std::string(IFN.begin(), IFN.end()-3)+".ll"; 100193323Sed } else { 101193323Sed OutputFilename = IFN+".ll"; 102193323Sed } 103193323Sed 104193323Sed if (!Force && std::ifstream(OutputFilename.c_str())) { 105193323Sed // If force is not specified, make sure not to overwrite a file! 106193323Sed cerr << argv[0] << ": error opening '" << OutputFilename 107193323Sed << "': file exists! Sending to standard output.\n"; 108193323Sed } else { 109193323Sed Out = new std::ofstream(OutputFilename.c_str()); 110193323Sed 111193323Sed // Make sure that the Out file gets unlinked from the disk if we get a 112193323Sed // SIGINT 113193323Sed sys::RemoveFileOnSignal(sys::Path(OutputFilename)); 114193323Sed } 115193323Sed } 116193323Sed } 117193323Sed 118193323Sed if (!Out->good()) { 119193323Sed cerr << argv[0] << ": error opening " << OutputFilename 120193323Sed << ": sending to stdout instead!\n"; 121193323Sed Out = &std::cout; 122193323Sed } 123193323Sed 124193323Sed // All that llvm-dis does is write the assembly to a file. 125193323Sed if (!DontPrint) { 126193323Sed PassManager Passes; 127193323Sed raw_os_ostream L(*Out); 128193323Sed Passes.add(createPrintModulePass(&L)); 129193323Sed Passes.run(*M.get()); 130193323Sed } 131193323Sed 132193323Sed if (Out != &std::cout) { 133193323Sed ((std::ofstream*)Out)->close(); 134193323Sed delete Out; 135193323Sed } 136193323Sed return 0; 137193323Sed } catch (const std::string& msg) { 138193323Sed cerr << argv[0] << ": " << msg << "\n"; 139193323Sed } catch (...) { 140193323Sed cerr << argv[0] << ": Unexpected unknown exception occurred.\n"; 141193323Sed } 142193323Sed 143193323Sed return 1; 144193323Sed} 145193323Sed 146