llvm-dis.cpp revision 249423
1230557Sjimharris//===-- llvm-dis.cpp - The low-level LLVM disassembler --------------------===// 2230557Sjimharris// 3230557Sjimharris// The LLVM Compiler Infrastructure 4230557Sjimharris// 5230557Sjimharris// This file is distributed under the University of Illinois Open Source 6230557Sjimharris// License. See LICENSE.TXT for details. 7230557Sjimharris// 8230557Sjimharris//===----------------------------------------------------------------------===// 9230557Sjimharris// 10230557Sjimharris// This utility may be invoked in the following manner: 11230557Sjimharris// llvm-dis [options] - Read LLVM bitcode from stdin, write asm to stdout 12230557Sjimharris// llvm-dis [options] x.bc - Read LLVM bitcode from the x.bc file, write asm 13230557Sjimharris// to the x.ll file. 14230557Sjimharris// Options: 15230557Sjimharris// --help - Output information about command line switches 16230557Sjimharris// 17230557Sjimharris//===----------------------------------------------------------------------===// 18230557Sjimharris 19230557Sjimharris#include "llvm/IR/LLVMContext.h" 20230557Sjimharris#include "llvm/Assembly/AssemblyAnnotationWriter.h" 21230557Sjimharris#include "llvm/Bitcode/ReaderWriter.h" 22230557Sjimharris#include "llvm/DebugInfo.h" 23230557Sjimharris#include "llvm/IR/IntrinsicInst.h" 24230557Sjimharris#include "llvm/IR/Module.h" 25230557Sjimharris#include "llvm/IR/Type.h" 26230557Sjimharris#include "llvm/Support/CommandLine.h" 27230557Sjimharris#include "llvm/Support/DataStream.h" 28230557Sjimharris#include "llvm/Support/FormattedStream.h" 29230557Sjimharris#include "llvm/Support/ManagedStatic.h" 30230557Sjimharris#include "llvm/Support/MemoryBuffer.h" 31230557Sjimharris#include "llvm/Support/PrettyStackTrace.h" 32230557Sjimharris#include "llvm/Support/Signals.h" 33230557Sjimharris#include "llvm/Support/ToolOutputFile.h" 34230557Sjimharris#include "llvm/Support/system_error.h" 35230557Sjimharrisusing namespace llvm; 36230557Sjimharris 37230557Sjimharrisstatic cl::opt<std::string> 38230557SjimharrisInputFilename(cl::Positional, cl::desc("<input bitcode>"), cl::init("-")); 39230557Sjimharris 40230557Sjimharrisstatic cl::opt<std::string> 41230557SjimharrisOutputFilename("o", cl::desc("Override output filename"), 42230557Sjimharris cl::value_desc("filename")); 43230557Sjimharris 44230557Sjimharrisstatic cl::opt<bool> 45230557SjimharrisForce("f", cl::desc("Enable binary output on terminals")); 46230557Sjimharris 47230557Sjimharrisstatic cl::opt<bool> 48230557SjimharrisDontPrint("disable-output", cl::desc("Don't output the .ll file"), cl::Hidden); 49230557Sjimharris 50230557Sjimharrisstatic cl::opt<bool> 51230557SjimharrisShowAnnotations("show-annotations", 52230557Sjimharris cl::desc("Add informational comments to the .ll file")); 53230557Sjimharris 54230557Sjimharrisnamespace { 55230557Sjimharris 56230557Sjimharrisstatic void printDebugLoc(const DebugLoc &DL, formatted_raw_ostream &OS) { 57230557Sjimharris OS << DL.getLine() << ":" << DL.getCol(); 58230557Sjimharris if (MDNode *N = DL.getInlinedAt(getGlobalContext())) { 59230557Sjimharris DebugLoc IDL = DebugLoc::getFromDILocation(N); 60230557Sjimharris if (!IDL.isUnknown()) { 61230557Sjimharris OS << "@"; 62230557Sjimharris printDebugLoc(IDL,OS); 63230557Sjimharris } 64230557Sjimharris } 65230557Sjimharris} 66230557Sjimharrisclass CommentWriter : public AssemblyAnnotationWriter { 67230557Sjimharrispublic: 68230557Sjimharris void emitFunctionAnnot(const Function *F, 69230557Sjimharris formatted_raw_ostream &OS) { 70230557Sjimharris OS << "; [#uses=" << F->getNumUses() << ']'; // Output # uses 71230557Sjimharris OS << '\n'; 72230557Sjimharris } 73230557Sjimharris void printInfoComment(const Value &V, formatted_raw_ostream &OS) { 74230557Sjimharris bool Padded = false; 75230557Sjimharris if (!V.getType()->isVoidTy()) { 76230557Sjimharris OS.PadToColumn(50); 77230557Sjimharris Padded = true; 78230557Sjimharris OS << "; [#uses=" << V.getNumUses() << " type=" << *V.getType() << "]"; // Output # uses and type 79230557Sjimharris } 80230557Sjimharris if (const Instruction *I = dyn_cast<Instruction>(&V)) { 81230557Sjimharris const DebugLoc &DL = I->getDebugLoc(); 82230557Sjimharris if (!DL.isUnknown()) { 83230557Sjimharris if (!Padded) { 84230557Sjimharris OS.PadToColumn(50); 85230557Sjimharris Padded = true; 86230557Sjimharris OS << ";"; 87230557Sjimharris } 88230557Sjimharris OS << " [debug line = "; 89230557Sjimharris printDebugLoc(DL,OS); 90230557Sjimharris OS << "]"; 91230557Sjimharris } 92230557Sjimharris if (const DbgDeclareInst *DDI = dyn_cast<DbgDeclareInst>(I)) { 93230557Sjimharris DIVariable Var(DDI->getVariable()); 94230557Sjimharris if (!Padded) { 95230557Sjimharris OS.PadToColumn(50); 96230557Sjimharris OS << ";"; 97230557Sjimharris } 98230557Sjimharris OS << " [debug variable = " << Var.getName() << "]"; 99230557Sjimharris } 100230557Sjimharris else if (const DbgValueInst *DVI = dyn_cast<DbgValueInst>(I)) { 101230557Sjimharris DIVariable Var(DVI->getVariable()); 102230557Sjimharris if (!Padded) { 103230557Sjimharris OS.PadToColumn(50); 104230557Sjimharris OS << ";"; 105230557Sjimharris } 106230557Sjimharris OS << " [debug variable = " << Var.getName() << "]"; 107230557Sjimharris } 108230557Sjimharris } 109230557Sjimharris } 110230557Sjimharris}; 111230557Sjimharris 112230557Sjimharris} // end anon namespace 113230557Sjimharris 114230557Sjimharrisint main(int argc, char **argv) { 115230557Sjimharris // Print a stack trace if we signal out. 116230557Sjimharris sys::PrintStackTraceOnErrorSignal(); 117230557Sjimharris PrettyStackTraceProgram X(argc, argv); 118230557Sjimharris 119230557Sjimharris LLVMContext &Context = getGlobalContext(); 120230557Sjimharris llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. 121230557Sjimharris 122230557Sjimharris 123230557Sjimharris cl::ParseCommandLineOptions(argc, argv, "llvm .bc -> .ll disassembler\n"); 124230557Sjimharris 125230557Sjimharris std::string ErrorMessage; 126230557Sjimharris std::auto_ptr<Module> M; 127230557Sjimharris 128230557Sjimharris // Use the bitcode streaming interface 129230557Sjimharris DataStreamer *streamer = getDataFileStreamer(InputFilename, &ErrorMessage); 130230557Sjimharris if (streamer) { 131230557Sjimharris std::string DisplayFilename; 132230557Sjimharris if (InputFilename == "-") 133230557Sjimharris DisplayFilename = "<stdin>"; 134230557Sjimharris else 135230557Sjimharris DisplayFilename = InputFilename; 136230557Sjimharris M.reset(getStreamedBitcodeModule(DisplayFilename, streamer, Context, 137230557Sjimharris &ErrorMessage)); 138230557Sjimharris if(M.get() != 0 && M->MaterializeAllPermanently(&ErrorMessage)) { 139230557Sjimharris M.reset(); 140230557Sjimharris } 141230557Sjimharris } 142230557Sjimharris 143230557Sjimharris if (M.get() == 0) { 144230557Sjimharris errs() << argv[0] << ": "; 145230557Sjimharris if (ErrorMessage.size()) 146230557Sjimharris errs() << ErrorMessage << "\n"; 147230557Sjimharris else 148230557Sjimharris errs() << "bitcode didn't read correctly.\n"; 149230557Sjimharris return 1; 150230557Sjimharris } 151230557Sjimharris 152230557Sjimharris // Just use stdout. We won't actually print anything on it. 153230557Sjimharris if (DontPrint) 154230557Sjimharris OutputFilename = "-"; 155230557Sjimharris 156230557Sjimharris if (OutputFilename.empty()) { // Unspecified output, infer it. 157230557Sjimharris if (InputFilename == "-") { 158230557Sjimharris OutputFilename = "-"; 159230557Sjimharris } else { 160230557Sjimharris const std::string &IFN = InputFilename; 161230557Sjimharris int Len = IFN.length(); 162230557Sjimharris // If the source ends in .bc, strip it off. 163230557Sjimharris if (IFN[Len-3] == '.' && IFN[Len-2] == 'b' && IFN[Len-1] == 'c') 164230557Sjimharris OutputFilename = std::string(IFN.begin(), IFN.end()-3)+".ll"; 165230557Sjimharris else 166230557Sjimharris OutputFilename = IFN+".ll"; 167230557Sjimharris } 168230557Sjimharris } 169230557Sjimharris 170230557Sjimharris std::string ErrorInfo; 171230557Sjimharris OwningPtr<tool_output_file> 172230557Sjimharris Out(new tool_output_file(OutputFilename.c_str(), ErrorInfo, 173230557Sjimharris raw_fd_ostream::F_Binary)); 174230557Sjimharris if (!ErrorInfo.empty()) { 175230557Sjimharris errs() << ErrorInfo << '\n'; 176230557Sjimharris return 1; 177230557Sjimharris } 178230557Sjimharris 179230557Sjimharris OwningPtr<AssemblyAnnotationWriter> Annotator; 180230557Sjimharris if (ShowAnnotations) 181230557Sjimharris Annotator.reset(new CommentWriter()); 182230557Sjimharris 183230557Sjimharris // All that llvm-dis does is write the assembly to a file. 184230557Sjimharris if (!DontPrint) 185230557Sjimharris M->print(Out->os(), Annotator.get()); 186230557Sjimharris 187230557Sjimharris // Declare success. 188230557Sjimharris Out->keep(); 189230557Sjimharris 190230557Sjimharris return 0; 191230557Sjimharris} 192230557Sjimharris