llvm-dis.cpp revision 193323
1189251Ssam//===-- llvm-dis.cpp - The low-level LLVM disassembler --------------------===// 2189251Ssam// 3281806Srpaulo// The LLVM Compiler Infrastructure 4189251Ssam// 5252726Srpaulo// This file is distributed under the University of Illinois Open Source 6252726Srpaulo// License. See LICENSE.TXT for details. 7189251Ssam// 8189251Ssam//===----------------------------------------------------------------------===// 9189251Ssam// 10189251Ssam// This utility may be invoked in the following manner: 11189251Ssam// llvm-dis [options] - Read LLVM bitcode from stdin, write asm to stdout 12189251Ssam// llvm-dis [options] x.bc - Read LLVM bitcode from the x.bc file, write asm 13189775Ssam// to the x.ll file. 14252726Srpaulo// Options: 15252726Srpaulo// --help - Output information about command line switches 16289549Srpaulo// 17289549Srpaulo//===----------------------------------------------------------------------===// 18289549Srpaulo 19289549Srpaulo#include "llvm/Module.h" 20252726Srpaulo#include "llvm/PassManager.h" 21252726Srpaulo#include "llvm/Bitcode/ReaderWriter.h" 22252726Srpaulo#include "llvm/Assembly/PrintModulePass.h" 23189251Ssam#include "llvm/Support/CommandLine.h" 24214734Srpaulo#include "llvm/Support/ManagedStatic.h" 25214734Srpaulo#include "llvm/Support/MemoryBuffer.h" 26214734Srpaulo#include "llvm/Support/PrettyStackTrace.h" 27214734Srpaulo#include "llvm/Support/Streams.h" 28189251Ssam#include "llvm/Support/raw_ostream.h" 29189251Ssam#include "llvm/System/Signals.h" 30189251Ssam#include <iostream> 31189251Ssam#include <fstream> 32189251Ssam#include <memory> 33189251Ssamusing namespace llvm; 34189251Ssam 35189251Ssamstatic cl::opt<std::string> 36189251SsamInputFilename(cl::Positional, cl::desc("<input bitcode>"), cl::init("-")); 37189251Ssam 38189251Ssamstatic cl::opt<std::string> 39189251SsamOutputFilename("o", cl::desc("Override output filename"), 40189251Ssam cl::value_desc("filename")); 41189251Ssam 42214734Srpaulostatic cl::opt<bool> 43189251SsamForce("f", cl::desc("Overwrite output files")); 44189251Ssam 45189251Ssamstatic cl::opt<bool> 46189251SsamDontPrint("disable-output", cl::desc("Don't output the .ll file"), cl::Hidden); 47189251Ssam 48189251Ssamint main(int argc, char **argv) { 49189251Ssam // Print a stack trace if we signal out. 50189251Ssam sys::PrintStackTraceOnErrorSignal(); 51189251Ssam PrettyStackTraceProgram X(argc, argv); 52189251Ssam 53214734Srpaulo llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. 54281806Srpaulo try { 55189251Ssam cl::ParseCommandLineOptions(argc, argv, "llvm .bc -> .ll disassembler\n"); 56189251Ssam 57189251Ssam std::ostream *Out = &std::cout; // Default to printing to stdout. 58281806Srpaulo std::string ErrorMessage; 59281806Srpaulo 60281806Srpaulo std::auto_ptr<Module> M; 61281806Srpaulo 62281806Srpaulo if (MemoryBuffer *Buffer 63281806Srpaulo = MemoryBuffer::getFileOrSTDIN(InputFilename, &ErrorMessage)) { 64281806Srpaulo M.reset(ParseBitcodeFile(Buffer, &ErrorMessage)); 65281806Srpaulo delete Buffer; 66281806Srpaulo } 67281806Srpaulo 68281806Srpaulo if (M.get() == 0) { 69189251Ssam cerr << argv[0] << ": "; 70281806Srpaulo if (ErrorMessage.size()) 71281806Srpaulo cerr << ErrorMessage << "\n"; 72281806Srpaulo else 73281806Srpaulo cerr << "bitcode didn't read correctly.\n"; 74281806Srpaulo return 1; 75281806Srpaulo } 76281806Srpaulo 77189251Ssam if (DontPrint) { 78189251Ssam // Just use stdout. We won't actually print anything on it. 79289549Srpaulo } else if (OutputFilename != "") { // Specified an output filename? 80289549Srpaulo if (OutputFilename != "-") { // Not stdout? 81289549Srpaulo if (!Force && std::ifstream(OutputFilename.c_str())) { 82289549Srpaulo // If force is not specified, make sure not to overwrite a file! 83289549Srpaulo cerr << argv[0] << ": error opening '" << OutputFilename 84289549Srpaulo << "': file exists! Sending to standard output.\n"; 85289549Srpaulo } else { 86289549Srpaulo Out = new std::ofstream(OutputFilename.c_str()); 87289549Srpaulo } 88289549Srpaulo } 89289549Srpaulo } else { 90289549Srpaulo if (InputFilename == "-") { 91289549Srpaulo OutputFilename = "-"; 92289549Srpaulo } else { 93289549Srpaulo std::string IFN = InputFilename; 94289549Srpaulo int Len = IFN.length(); 95289549Srpaulo if (IFN[Len-3] == '.' && IFN[Len-2] == 'b' && IFN[Len-1] == 'c') { 96289549Srpaulo // Source ends in .bc 97289549Srpaulo OutputFilename = std::string(IFN.begin(), IFN.end()-3)+".ll"; 98289549Srpaulo } else { 99289549Srpaulo OutputFilename = IFN+".ll"; 100289549Srpaulo } 101289549Srpaulo 102289549Srpaulo if (!Force && std::ifstream(OutputFilename.c_str())) { 103289549Srpaulo // If force is not specified, make sure not to overwrite a file! 104289549Srpaulo cerr << argv[0] << ": error opening '" << OutputFilename 105281806Srpaulo << "': file exists! Sending to standard output.\n"; 106189251Ssam } else { 107281806Srpaulo Out = new std::ofstream(OutputFilename.c_str()); 108189251Ssam 109189251Ssam // Make sure that the Out file gets unlinked from the disk if we get a 110281806Srpaulo // SIGINT 111189251Ssam sys::RemoveFileOnSignal(sys::Path(OutputFilename)); 112189251Ssam } 113189251Ssam } 114189251Ssam } 115189251Ssam 116189251Ssam if (!Out->good()) { 117189251Ssam cerr << argv[0] << ": error opening " << OutputFilename 118281806Srpaulo << ": sending to stdout instead!\n"; 119281806Srpaulo Out = &std::cout; 120281806Srpaulo } 121281806Srpaulo 122281806Srpaulo // All that llvm-dis does is write the assembly to a file. 123281806Srpaulo if (!DontPrint) { 124189251Ssam PassManager Passes; 125189251Ssam raw_os_ostream L(*Out); 126189251Ssam Passes.add(createPrintModulePass(&L)); 127189251Ssam Passes.run(*M.get()); 128281806Srpaulo } 129189251Ssam 130189251Ssam if (Out != &std::cout) { 131189251Ssam ((std::ofstream*)Out)->close(); 132214734Srpaulo delete Out; 133189251Ssam } 134281806Srpaulo return 0; 135189251Ssam } catch (const std::string& msg) { 136189251Ssam cerr << argv[0] << ": " << msg << "\n"; 137209158Srpaulo } catch (...) { 138209158Srpaulo cerr << argv[0] << ": Unexpected unknown exception occurred.\n"; 139281806Srpaulo } 140281806Srpaulo 141281806Srpaulo return 1; 142281806Srpaulo} 143281806Srpaulo 144281806Srpaulo