llvm-dis.cpp revision c7a0985995631025fbe9a4fe9fc435c3ba7387e4
11d7b50b4f823012dc283e46c2bd8036d32b402f4Chris Lattner//===----------------------------------------------------------------------===// 2009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// LLVM 'DIS' UTILITY 3009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// 4009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// This utility may be invoked in the following manner: 5009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// dis [options] - Read LLVM bytecode from stdin, write assembly to stdout 6009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// dis [options] x.bc - Read LLVM bytecode from the x.bc file, write assembly 7009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// to the x.ll file. 89bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner// Options: 99bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner// --help - Output information about command line switches 10aa3904faffd930c9f428863055dee58a89418dd8Chris Lattner// -c - Print C code instead of LLVM assembly 11009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// 121d7b50b4f823012dc283e46c2bd8036d32b402f4Chris Lattner//===----------------------------------------------------------------------===// 13009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 14009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner#include "llvm/Module.h" 15009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner#include "llvm/Bytecode/Reader.h" 16221d688a5ef21a22c2368c9fff0e92d7966c95e5Chris Lattner#include "llvm/Support/CFG.h" 17cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner#include "Support/CommandLine.h" 1876d12299b5333d71bfc079614031f97c97aa5148Chris Lattner#include "Support/Signals.h" 199ddc86c6e51617d1170eed07a4320edf6679f655Sumant Kowshik#include "llvm/Assembly/CWriter.h" 20cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner#include <fstream> 21697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner#include <iostream> 22697954c15da58bd8b186dbafdedd8b06db770201Chris Lattnerusing std::cerr; 23009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 248f367bd3c0f56b7b318c46cee04f77735f617777Chris Lattner// OutputMode - The different orderings to print basic blocks in... 258f367bd3c0f56b7b318c46cee04f77735f617777Chris Lattnerenum OutputMode { 26aa3904faffd930c9f428863055dee58a89418dd8Chris Lattner llvm = 0, // Generate LLVM assembly (the default) 27aa3904faffd930c9f428863055dee58a89418dd8Chris Lattner c, // Generate C code 288f367bd3c0f56b7b318c46cee04f77735f617777Chris Lattner}; 299bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner 30c7a0985995631025fbe9a4fe9fc435c3ba7387e4Chris Lattnerstatic cl::opt<std::string> 315ff62e90d0bc321206023897edc1e2691cb0fbb6Chris LattnerInputFilename(cl::Positional, cl::desc("<input bytecode>"), cl::init("-")); 325ff62e90d0bc321206023897edc1e2691cb0fbb6Chris Lattner 33c7a0985995631025fbe9a4fe9fc435c3ba7387e4Chris Lattnerstatic cl::opt<std::string> 345ff62e90d0bc321206023897edc1e2691cb0fbb6Chris LattnerOutputFilename("o", cl::desc("Override output filename"), 355ff62e90d0bc321206023897edc1e2691cb0fbb6Chris Lattner cl::value_desc("filename")); 365ff62e90d0bc321206023897edc1e2691cb0fbb6Chris Lattner 375ff62e90d0bc321206023897edc1e2691cb0fbb6Chris Lattnerstatic cl::opt<bool> 385ff62e90d0bc321206023897edc1e2691cb0fbb6Chris LattnerForce("f", cl::desc("Overwrite output files")); 395ff62e90d0bc321206023897edc1e2691cb0fbb6Chris Lattner 405ff62e90d0bc321206023897edc1e2691cb0fbb6Chris Lattnerstatic cl::opt<enum OutputMode> 415ff62e90d0bc321206023897edc1e2691cb0fbb6Chris LattnerWriteMode(cl::desc("Specify the output format:"), 425ff62e90d0bc321206023897edc1e2691cb0fbb6Chris Lattner cl::values( 435ff62e90d0bc321206023897edc1e2691cb0fbb6Chris Lattner clEnumVal(llvm, "Output LLVM assembly"), 445ff62e90d0bc321206023897edc1e2691cb0fbb6Chris Lattner clEnumVal(c , "Output C code for program"), 455ff62e90d0bc321206023897edc1e2691cb0fbb6Chris Lattner 0)); 46009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 478f367bd3c0f56b7b318c46cee04f77735f617777Chris Lattnerint main(int argc, char **argv) { 488f367bd3c0f56b7b318c46cee04f77735f617777Chris Lattner cl::ParseCommandLineOptions(argc, argv, " llvm .bc -> .ll disassembler\n"); 49697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner std::ostream *Out = &std::cout; // Default to printing to stdout... 50009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 512fbfdcffd3e0cf41422aaa6c526c37cb02b81341Chris Lattner Module *M = ParseBytecodeFile(InputFilename); 522fbfdcffd3e0cf41422aaa6c526c37cb02b81341Chris Lattner if (M == 0) { 53009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner cerr << "bytecode didn't read correctly.\n"; 54009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner return 1; 55009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner } 56009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 571e78f36127fb0e405d2cf893e2ce3381300a667bChris Lattner if (OutputFilename != "") { // Specified an output filename? 58888912dbe01c715aa5a0ddec19da6ef12f382ebfChris Lattner if (!Force && std::ifstream(OutputFilename.c_str())) { 59697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner // If force is not specified, make sure not to overwrite a file! 60697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner cerr << "Error opening '" << OutputFilename 61697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner << "': File exists! Sending to standard output.\n"; 62697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner } else { 63697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner Out = new std::ofstream(OutputFilename.c_str()); 64697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner } 658f367bd3c0f56b7b318c46cee04f77735f617777Chris Lattner } else { 661e78f36127fb0e405d2cf893e2ce3381300a667bChris Lattner if (InputFilename == "-") { 671e78f36127fb0e405d2cf893e2ce3381300a667bChris Lattner OutputFilename = "-"; 688f367bd3c0f56b7b318c46cee04f77735f617777Chris Lattner } else { 69697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner std::string IFN = InputFilename; 708f367bd3c0f56b7b318c46cee04f77735f617777Chris Lattner int Len = IFN.length(); 718f367bd3c0f56b7b318c46cee04f77735f617777Chris Lattner if (IFN[Len-3] == '.' && IFN[Len-2] == 'b' && IFN[Len-1] == 'c') { 728f367bd3c0f56b7b318c46cee04f77735f617777Chris Lattner // Source ends in .bc 73697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner OutputFilename = std::string(IFN.begin(), IFN.end()-3); 748f367bd3c0f56b7b318c46cee04f77735f617777Chris Lattner } else { 751e78f36127fb0e405d2cf893e2ce3381300a667bChris Lattner OutputFilename = IFN; // Append a .ll to it 76009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner } 779ddc86c6e51617d1170eed07a4320edf6679f655Sumant Kowshik if (WriteMode == c) 78aa3904faffd930c9f428863055dee58a89418dd8Chris Lattner OutputFilename += ".c"; 799ddc86c6e51617d1170eed07a4320edf6679f655Sumant Kowshik else 80aa3904faffd930c9f428863055dee58a89418dd8Chris Lattner OutputFilename += ".ll"; 81697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner 82888912dbe01c715aa5a0ddec19da6ef12f382ebfChris Lattner if (!Force && std::ifstream(OutputFilename.c_str())) { 83697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner // If force is not specified, make sure not to overwrite a file! 84697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner cerr << "Error opening '" << OutputFilename 85697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner << "': File exists! Sending to standard output.\n"; 86697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner } else { 87697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner Out = new std::ofstream(OutputFilename.c_str()); 8876d12299b5333d71bfc079614031f97c97aa5148Chris Lattner 8976d12299b5333d71bfc079614031f97c97aa5148Chris Lattner // Make sure that the Out file gets unlink'd from the disk if we get a 9076d12299b5333d71bfc079614031f97c97aa5148Chris Lattner // SIGINT 9176d12299b5333d71bfc079614031f97c97aa5148Chris Lattner RemoveFileOnSignal(OutputFilename); 92697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner } 938f367bd3c0f56b7b318c46cee04f77735f617777Chris Lattner } 94009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner } 958f367bd3c0f56b7b318c46cee04f77735f617777Chris Lattner 968f367bd3c0f56b7b318c46cee04f77735f617777Chris Lattner if (!Out->good()) { 971e78f36127fb0e405d2cf893e2ce3381300a667bChris Lattner cerr << "Error opening " << OutputFilename 988f367bd3c0f56b7b318c46cee04f77735f617777Chris Lattner << ": sending to stdout instead!\n"; 99697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner Out = &std::cout; 1008f367bd3c0f56b7b318c46cee04f77735f617777Chris Lattner } 1018f367bd3c0f56b7b318c46cee04f77735f617777Chris Lattner 102aa3904faffd930c9f428863055dee58a89418dd8Chris Lattner // All that dis does is write the assembly or C out to a file... 103aa3904faffd930c9f428863055dee58a89418dd8Chris Lattner // 104aa3904faffd930c9f428863055dee58a89418dd8Chris Lattner switch (WriteMode) { 105aa3904faffd930c9f428863055dee58a89418dd8Chris Lattner case llvm: 106aa3904faffd930c9f428863055dee58a89418dd8Chris Lattner (*Out) << M; // Output LLVM assembly 107aa3904faffd930c9f428863055dee58a89418dd8Chris Lattner break; 108aa3904faffd930c9f428863055dee58a89418dd8Chris Lattner case c: 109aa3904faffd930c9f428863055dee58a89418dd8Chris Lattner WriteToC(M, *Out); // Convert LLVM to C 110aa3904faffd930c9f428863055dee58a89418dd8Chris Lattner break; 1119bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner } 1122fbfdcffd3e0cf41422aaa6c526c37cb02b81341Chris Lattner delete M; 113009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 114697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner if (Out != &std::cout) delete Out; 115009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner return 0; 116009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner} 1179ddc86c6e51617d1170eed07a4320edf6679f655Sumant Kowshik 118