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 19249423Sdim#include "llvm/IR/LLVMContext.h" 20249423Sdim#include "llvm/Assembly/AssemblyAnnotationWriter.h" 21249423Sdim#include "llvm/Bitcode/ReaderWriter.h" 22239462Sdim#include "llvm/DebugInfo.h" 23249423Sdim#include "llvm/IR/IntrinsicInst.h" 24249423Sdim#include "llvm/IR/Module.h" 25249423Sdim#include "llvm/IR/Type.h" 26193323Sed#include "llvm/Support/CommandLine.h" 27234353Sdim#include "llvm/Support/DataStream.h" 28212793Sdim#include "llvm/Support/FormattedStream.h" 29193323Sed#include "llvm/Support/ManagedStatic.h" 30193323Sed#include "llvm/Support/MemoryBuffer.h" 31193323Sed#include "llvm/Support/PrettyStackTrace.h" 32249423Sdim#include "llvm/Support/Signals.h" 33218885Sdim#include "llvm/Support/ToolOutputFile.h" 34218885Sdim#include "llvm/Support/system_error.h" 35193323Sedusing namespace llvm; 36193323Sed 37193323Sedstatic cl::opt<std::string> 38193323SedInputFilename(cl::Positional, cl::desc("<input bitcode>"), cl::init("-")); 39193323Sed 40193323Sedstatic cl::opt<std::string> 41193323SedOutputFilename("o", cl::desc("Override output filename"), 42193323Sed cl::value_desc("filename")); 43193323Sed 44193323Sedstatic cl::opt<bool> 45198090SrdivackyForce("f", cl::desc("Enable binary output on terminals")); 46193323Sed 47193323Sedstatic cl::opt<bool> 48193323SedDontPrint("disable-output", cl::desc("Don't output the .ll file"), cl::Hidden); 49193323Sed 50212793Sdimstatic cl::opt<bool> 51212793SdimShowAnnotations("show-annotations", 52212793Sdim cl::desc("Add informational comments to the .ll file")); 53212793Sdim 54212793Sdimnamespace { 55218885Sdim 56221337Sdimstatic void printDebugLoc(const DebugLoc &DL, formatted_raw_ostream &OS) { 57221337Sdim OS << DL.getLine() << ":" << DL.getCol(); 58221337Sdim if (MDNode *N = DL.getInlinedAt(getGlobalContext())) { 59221337Sdim DebugLoc IDL = DebugLoc::getFromDILocation(N); 60221337Sdim if (!IDL.isUnknown()) { 61221337Sdim OS << "@"; 62221337Sdim printDebugLoc(IDL,OS); 63221337Sdim } 64221337Sdim } 65221337Sdim} 66212793Sdimclass CommentWriter : public AssemblyAnnotationWriter { 67212793Sdimpublic: 68212793Sdim void emitFunctionAnnot(const Function *F, 69212793Sdim formatted_raw_ostream &OS) { 70212793Sdim OS << "; [#uses=" << F->getNumUses() << ']'; // Output # uses 71212793Sdim OS << '\n'; 72212793Sdim } 73212793Sdim void printInfoComment(const Value &V, formatted_raw_ostream &OS) { 74221337Sdim bool Padded = false; 75221337Sdim if (!V.getType()->isVoidTy()) { 76221337Sdim OS.PadToColumn(50); 77221337Sdim Padded = true; 78224133Sdim OS << "; [#uses=" << V.getNumUses() << " type=" << *V.getType() << "]"; // Output # uses and type 79221337Sdim } 80221337Sdim if (const Instruction *I = dyn_cast<Instruction>(&V)) { 81221337Sdim const DebugLoc &DL = I->getDebugLoc(); 82221337Sdim if (!DL.isUnknown()) { 83221337Sdim if (!Padded) { 84221337Sdim OS.PadToColumn(50); 85221337Sdim Padded = true; 86221337Sdim OS << ";"; 87221337Sdim } 88221337Sdim OS << " [debug line = "; 89221337Sdim printDebugLoc(DL,OS); 90221337Sdim OS << "]"; 91221337Sdim } 92221337Sdim if (const DbgDeclareInst *DDI = dyn_cast<DbgDeclareInst>(I)) { 93221337Sdim DIVariable Var(DDI->getVariable()); 94221337Sdim if (!Padded) { 95221337Sdim OS.PadToColumn(50); 96221337Sdim OS << ";"; 97221337Sdim } 98221337Sdim OS << " [debug variable = " << Var.getName() << "]"; 99221337Sdim } 100221337Sdim else if (const DbgValueInst *DVI = dyn_cast<DbgValueInst>(I)) { 101221337Sdim DIVariable Var(DVI->getVariable()); 102221337Sdim if (!Padded) { 103221337Sdim OS.PadToColumn(50); 104221337Sdim OS << ";"; 105221337Sdim } 106221337Sdim OS << " [debug variable = " << Var.getName() << "]"; 107221337Sdim } 108221337Sdim } 109212793Sdim } 110212793Sdim}; 111218885Sdim 112212793Sdim} // end anon namespace 113212793Sdim 114193323Sedint main(int argc, char **argv) { 115193323Sed // Print a stack trace if we signal out. 116193323Sed sys::PrintStackTraceOnErrorSignal(); 117193323Sed PrettyStackTraceProgram X(argc, argv); 118218885Sdim 119198090Srdivacky LLVMContext &Context = getGlobalContext(); 120193323Sed llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. 121218885Sdim 122218885Sdim 123198090Srdivacky cl::ParseCommandLineOptions(argc, argv, "llvm .bc -> .ll disassembler\n"); 124193323Sed 125198090Srdivacky std::string ErrorMessage; 126251662Sdim OwningPtr<Module> M; 127218885Sdim 128234353Sdim // Use the bitcode streaming interface 129234353Sdim DataStreamer *streamer = getDataFileStreamer(InputFilename, &ErrorMessage); 130234353Sdim if (streamer) { 131234353Sdim std::string DisplayFilename; 132234353Sdim if (InputFilename == "-") 133234353Sdim DisplayFilename = "<stdin>"; 134218885Sdim else 135234353Sdim DisplayFilename = InputFilename; 136234353Sdim M.reset(getStreamedBitcodeModule(DisplayFilename, streamer, Context, 137234353Sdim &ErrorMessage)); 138234353Sdim if(M.get() != 0 && M->MaterializeAllPermanently(&ErrorMessage)) { 139234353Sdim M.reset(); 140234353Sdim } 141198090Srdivacky } 142193323Sed 143198090Srdivacky if (M.get() == 0) { 144198090Srdivacky errs() << argv[0] << ": "; 145198090Srdivacky if (ErrorMessage.size()) 146198090Srdivacky errs() << ErrorMessage << "\n"; 147198090Srdivacky else 148198090Srdivacky errs() << "bitcode didn't read correctly.\n"; 149198090Srdivacky return 1; 150198090Srdivacky } 151218885Sdim 152198090Srdivacky // Just use stdout. We won't actually print anything on it. 153198090Srdivacky if (DontPrint) 154198090Srdivacky OutputFilename = "-"; 155218885Sdim 156198090Srdivacky if (OutputFilename.empty()) { // Unspecified output, infer it. 157198090Srdivacky if (InputFilename == "-") { 158198090Srdivacky OutputFilename = "-"; 159198090Srdivacky } else { 160198090Srdivacky const std::string &IFN = InputFilename; 161198090Srdivacky int Len = IFN.length(); 162198090Srdivacky // If the source ends in .bc, strip it off. 163198090Srdivacky if (IFN[Len-3] == '.' && IFN[Len-2] == 'b' && IFN[Len-1] == 'c') 164198090Srdivacky OutputFilename = std::string(IFN.begin(), IFN.end()-3)+".ll"; 165193323Sed else 166198090Srdivacky OutputFilename = IFN+".ll"; 167193323Sed } 168198090Srdivacky } 169193323Sed 170198090Srdivacky std::string ErrorInfo; 171263508Sdim OwningPtr<tool_output_file> Out(new tool_output_file( 172263508Sdim OutputFilename.c_str(), ErrorInfo, sys::fs::F_Binary)); 173198090Srdivacky if (!ErrorInfo.empty()) { 174198090Srdivacky errs() << ErrorInfo << '\n'; 175198090Srdivacky return 1; 176198090Srdivacky } 177193323Sed 178212793Sdim OwningPtr<AssemblyAnnotationWriter> Annotator; 179212793Sdim if (ShowAnnotations) 180212793Sdim Annotator.reset(new CommentWriter()); 181218885Sdim 182198090Srdivacky // All that llvm-dis does is write the assembly to a file. 183198090Srdivacky if (!DontPrint) 184212793Sdim M->print(Out->os(), Annotator.get()); 185193323Sed 186212793Sdim // Declare success. 187212793Sdim Out->keep(); 188212793Sdim 189198090Srdivacky return 0; 190193323Sed} 191