llvm-dis.cpp revision 195340
1//===-- llvm-dis.cpp - The low-level LLVM disassembler --------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This utility may be invoked in the following manner: 11// llvm-dis [options] - Read LLVM bitcode from stdin, write asm to stdout 12// llvm-dis [options] x.bc - Read LLVM bitcode from the x.bc file, write asm 13// to the x.ll file. 14// Options: 15// --help - Output information about command line switches 16// 17//===----------------------------------------------------------------------===// 18 19#include "llvm/LLVMContext.h" 20#include "llvm/Module.h" 21#include "llvm/PassManager.h" 22#include "llvm/Bitcode/ReaderWriter.h" 23#include "llvm/Assembly/PrintModulePass.h" 24#include "llvm/Support/CommandLine.h" 25#include "llvm/Support/ManagedStatic.h" 26#include "llvm/Support/MemoryBuffer.h" 27#include "llvm/Support/PrettyStackTrace.h" 28#include "llvm/Support/Streams.h" 29#include "llvm/Support/raw_ostream.h" 30#include "llvm/System/Signals.h" 31#include <iostream> 32#include <fstream> 33#include <memory> 34using namespace llvm; 35 36static cl::opt<std::string> 37InputFilename(cl::Positional, cl::desc("<input bitcode>"), cl::init("-")); 38 39static cl::opt<std::string> 40OutputFilename("o", cl::desc("Override output filename"), 41 cl::value_desc("filename")); 42 43static cl::opt<bool> 44Force("f", cl::desc("Overwrite output files")); 45 46static cl::opt<bool> 47DontPrint("disable-output", cl::desc("Don't output the .ll file"), cl::Hidden); 48 49int main(int argc, char **argv) { 50 // Print a stack trace if we signal out. 51 sys::PrintStackTraceOnErrorSignal(); 52 PrettyStackTraceProgram X(argc, argv); 53 54 LLVMContext Context; 55 llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. 56 try { 57 cl::ParseCommandLineOptions(argc, argv, "llvm .bc -> .ll disassembler\n"); 58 59 std::ostream *Out = &std::cout; // Default to printing to stdout. 60 std::string ErrorMessage; 61 62 std::auto_ptr<Module> M; 63 64 if (MemoryBuffer *Buffer 65 = MemoryBuffer::getFileOrSTDIN(InputFilename, &ErrorMessage)) { 66 M.reset(ParseBitcodeFile(Buffer, Context, &ErrorMessage)); 67 delete Buffer; 68 } 69 70 if (M.get() == 0) { 71 cerr << argv[0] << ": "; 72 if (ErrorMessage.size()) 73 cerr << ErrorMessage << "\n"; 74 else 75 cerr << "bitcode didn't read correctly.\n"; 76 return 1; 77 } 78 79 if (DontPrint) { 80 // Just use stdout. We won't actually print anything on it. 81 } else if (OutputFilename != "") { // Specified an output filename? 82 if (OutputFilename != "-") { // Not stdout? 83 if (!Force && std::ifstream(OutputFilename.c_str())) { 84 // If force is not specified, make sure not to overwrite a file! 85 cerr << argv[0] << ": error opening '" << OutputFilename 86 << "': file exists! Sending to standard output.\n"; 87 } else { 88 Out = new std::ofstream(OutputFilename.c_str()); 89 } 90 } 91 } else { 92 if (InputFilename == "-") { 93 OutputFilename = "-"; 94 } else { 95 std::string IFN = InputFilename; 96 int Len = IFN.length(); 97 if (IFN[Len-3] == '.' && IFN[Len-2] == 'b' && IFN[Len-1] == 'c') { 98 // Source ends in .bc 99 OutputFilename = std::string(IFN.begin(), IFN.end()-3)+".ll"; 100 } else { 101 OutputFilename = IFN+".ll"; 102 } 103 104 if (!Force && std::ifstream(OutputFilename.c_str())) { 105 // If force is not specified, make sure not to overwrite a file! 106 cerr << argv[0] << ": error opening '" << OutputFilename 107 << "': file exists! Sending to standard output.\n"; 108 } else { 109 Out = new std::ofstream(OutputFilename.c_str()); 110 111 // Make sure that the Out file gets unlinked from the disk if we get a 112 // SIGINT 113 sys::RemoveFileOnSignal(sys::Path(OutputFilename)); 114 } 115 } 116 } 117 118 if (!Out->good()) { 119 cerr << argv[0] << ": error opening " << OutputFilename 120 << ": sending to stdout instead!\n"; 121 Out = &std::cout; 122 } 123 124 // All that llvm-dis does is write the assembly to a file. 125 if (!DontPrint) { 126 PassManager Passes; 127 raw_os_ostream L(*Out); 128 Passes.add(createPrintModulePass(&L)); 129 Passes.run(*M.get()); 130 } 131 132 if (Out != &std::cout) { 133 ((std::ofstream*)Out)->close(); 134 delete Out; 135 } 136 return 0; 137 } catch (const std::string& msg) { 138 cerr << argv[0] << ": " << msg << "\n"; 139 } catch (...) { 140 cerr << argv[0] << ": Unexpected unknown exception occurred.\n"; 141 } 142 143 return 1; 144} 145 146