llvm-dis.cpp revision ebe69fe11e48d322045d5949c83283927a0d790b
11dd27b157bbe7d9e44fa72abbc8b0f08eba804ecChris Lattner//===-- llvm-dis.cpp - The low-level LLVM disassembler --------------------===// 23da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman// 37c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell// The LLVM Compiler Infrastructure 47c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell// 521c62da287237d39d0d95004881ea4baae3be6daChris Lattner// This file is distributed under the University of Illinois Open Source 621c62da287237d39d0d95004881ea4baae3be6daChris Lattner// License. See LICENSE.TXT for details. 73da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman// 87c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell//===----------------------------------------------------------------------===// 9009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// 10009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// This utility may be invoked in the following manner: 11a99be51bf5cdac1438069d4b01766c47704961c8Gabor Greif// llvm-dis [options] - Read LLVM bitcode from stdin, write asm to stdout 12a99be51bf5cdac1438069d4b01766c47704961c8Gabor Greif// llvm-dis [options] x.bc - Read LLVM bitcode from the x.bc file, write asm 13ad0bf0fc0cead2c714d6a0e164d3bdb2864eb8e1Misha Brukman// to the x.ll file. 149bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner// Options: 159bff2e952226a80b65a993a81e87abe5216ffc48Chris Lattner// --help - Output information about command line switches 16009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// 171d7b50b4f823012dc283e46c2bd8036d32b402f4Chris Lattner//===----------------------------------------------------------------------===// 18009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 190b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/LLVMContext.h" 20f010c464a11444733ec67e31aace8bcebeaf2588Chandler Carruth#include "llvm/Bitcode/ReaderWriter.h" 2136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/AssemblyAnnotationWriter.h" 2236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/DebugInfo.h" 23ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/IR/DiagnosticInfo.h" 24ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/IR/DiagnosticPrinter.h" 250b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/IntrinsicInst.h" 260b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Module.h" 270b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Type.h" 28551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#include "llvm/Support/CommandLine.h" 292ea93875b2f2900b9d244dfd7649c9ed02a34cd7Derek Schuff#include "llvm/Support/DataStream.h" 30dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "llvm/Support/FileSystem.h" 316cd71f0c4026217a501e09dcc2198c6c7a462e44Chris Lattner#include "llvm/Support/FormattedStream.h" 32c30598bc3ad792eb8cc75b188eb872a28c62ab71Chris Lattner#include "llvm/Support/ManagedStatic.h" 33c453f76e2b4d7fd1e042b5b6d4c20556779186dfChris Lattner#include "llvm/Support/MemoryBuffer.h" 34cc14d25dd99e891c586bd56aa41796abbe4ac3d8Chris Lattner#include "llvm/Support/PrettyStackTrace.h" 351f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer#include "llvm/Support/Signals.h" 36f010c464a11444733ec67e31aace8bcebeaf2588Chandler Carruth#include "llvm/Support/ToolOutputFile.h" 37c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines#include <system_error> 38d0fde30ce850b78371fd1386338350591f9ff494Brian Gaekeusing namespace llvm; 39d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke 40c7a0985995631025fbe9a4fe9fc435c3ba7387e4Chris Lattnerstatic cl::opt<std::string> 41a99be51bf5cdac1438069d4b01766c47704961c8Gabor GreifInputFilename(cl::Positional, cl::desc("<input bitcode>"), cl::init("-")); 425ff62e90d0bc321206023897edc1e2691cb0fbb6Chris Lattner 43c7a0985995631025fbe9a4fe9fc435c3ba7387e4Chris Lattnerstatic cl::opt<std::string> 443da94aec4d429b2ba0f65fa040c33650cade196bMisha BrukmanOutputFilename("o", cl::desc("Override output filename"), 455ff62e90d0bc321206023897edc1e2691cb0fbb6Chris Lattner cl::value_desc("filename")); 465ff62e90d0bc321206023897edc1e2691cb0fbb6Chris Lattner 475ff62e90d0bc321206023897edc1e2691cb0fbb6Chris Lattnerstatic cl::opt<bool> 48baa26395ccf17fc988bb9cf62d6659ca8415ece9Dan GohmanForce("f", cl::desc("Enable binary output on terminals")); 495ff62e90d0bc321206023897edc1e2691cb0fbb6Chris Lattner 504d544cd646440fb99131206d6f074fa32dc308dcChris Lattnerstatic cl::opt<bool> 514d544cd646440fb99131206d6f074fa32dc308dcChris LattnerDontPrint("disable-output", cl::desc("Don't output the .ll file"), cl::Hidden); 524d544cd646440fb99131206d6f074fa32dc308dcChris Lattner 536cd71f0c4026217a501e09dcc2198c6c7a462e44Chris Lattnerstatic cl::opt<bool> 546cd71f0c4026217a501e09dcc2198c6c7a462e44Chris LattnerShowAnnotations("show-annotations", 556cd71f0c4026217a501e09dcc2198c6c7a462e44Chris Lattner cl::desc("Add informational comments to the .ll file")); 566cd71f0c4026217a501e09dcc2198c6c7a462e44Chris Lattner 576cd71f0c4026217a501e09dcc2198c6c7a462e44Chris Lattnernamespace { 587aa48441911e903803b75dfbcc148fbf80113819Michael J. Spencer 59027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patelstatic void printDebugLoc(const DebugLoc &DL, formatted_raw_ostream &OS) { 60027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel OS << DL.getLine() << ":" << DL.getCol(); 61027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel if (MDNode *N = DL.getInlinedAt(getGlobalContext())) { 62027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel DebugLoc IDL = DebugLoc::getFromDILocation(N); 63027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel if (!IDL.isUnknown()) { 64027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel OS << "@"; 65027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel printDebugLoc(IDL,OS); 66027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel } 67027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel } 68027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel} 696cd71f0c4026217a501e09dcc2198c6c7a462e44Chris Lattnerclass CommentWriter : public AssemblyAnnotationWriter { 706cd71f0c4026217a501e09dcc2198c6c7a462e44Chris Lattnerpublic: 716cd71f0c4026217a501e09dcc2198c6c7a462e44Chris Lattner void emitFunctionAnnot(const Function *F, 7236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines formatted_raw_ostream &OS) override { 736cd71f0c4026217a501e09dcc2198c6c7a462e44Chris Lattner OS << "; [#uses=" << F->getNumUses() << ']'; // Output # uses 746cd71f0c4026217a501e09dcc2198c6c7a462e44Chris Lattner OS << '\n'; 756cd71f0c4026217a501e09dcc2198c6c7a462e44Chris Lattner } 7636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void printInfoComment(const Value &V, formatted_raw_ostream &OS) override { 77027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel bool Padded = false; 78027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel if (!V.getType()->isVoidTy()) { 79027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel OS.PadToColumn(50); 80027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel Padded = true; 810cd0d881604775f3f97048645f040b2ef4f61e4bChris Lattner OS << "; [#uses=" << V.getNumUses() << " type=" << *V.getType() << "]"; // Output # uses and type 82027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel } 83027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel if (const Instruction *I = dyn_cast<Instruction>(&V)) { 84027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel const DebugLoc &DL = I->getDebugLoc(); 85027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel if (!DL.isUnknown()) { 86027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel if (!Padded) { 87027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel OS.PadToColumn(50); 88027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel Padded = true; 89027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel OS << ";"; 90027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel } 91027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel OS << " [debug line = "; 92027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel printDebugLoc(DL,OS); 93027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel OS << "]"; 94027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel } 95027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel if (const DbgDeclareInst *DDI = dyn_cast<DbgDeclareInst>(I)) { 96027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel DIVariable Var(DDI->getVariable()); 97027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel if (!Padded) { 98027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel OS.PadToColumn(50); 99027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel OS << ";"; 100027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel } 101027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel OS << " [debug variable = " << Var.getName() << "]"; 102027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel } 103027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel else if (const DbgValueInst *DVI = dyn_cast<DbgValueInst>(I)) { 104027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel DIVariable Var(DVI->getVariable()); 105027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel if (!Padded) { 106027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel OS.PadToColumn(50); 107027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel OS << ";"; 108027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel } 109027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel OS << " [debug variable = " << Var.getName() << "]"; 110027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel } 111027f0995d4f2a73836fe3225514c507f5c63deaeDevang Patel } 1126cd71f0c4026217a501e09dcc2198c6c7a462e44Chris Lattner } 1136cd71f0c4026217a501e09dcc2198c6c7a462e44Chris Lattner}; 1147aa48441911e903803b75dfbcc148fbf80113819Michael J. Spencer 1156cd71f0c4026217a501e09dcc2198c6c7a462e44Chris Lattner} // end anon namespace 1166cd71f0c4026217a501e09dcc2198c6c7a462e44Chris Lattner 117ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic void diagnosticHandler(const DiagnosticInfo &DI, void *Context) { 118ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines raw_ostream &OS = errs(); 119ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines OS << (char *)Context << ": "; 120ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines switch (DI.getSeverity()) { 121ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case DS_Error: OS << "error: "; break; 122ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case DS_Warning: OS << "warning: "; break; 123ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case DS_Remark: OS << "remark: "; break; 124ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case DS_Note: OS << "note: "; break; 125ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 126ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 127ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DiagnosticPrinterRawOStream DP(OS); 128ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DI.print(DP); 129ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines OS << '\n'; 130ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 131ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (DI.getSeverity() == DS_Error) 132ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines exit(1); 133ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 134ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 1358f367bd3c0f56b7b318c46cee04f77735f617777Chris Lattnerint main(int argc, char **argv) { 136cc14d25dd99e891c586bd56aa41796abbe4ac3d8Chris Lattner // Print a stack trace if we signal out. 137cc14d25dd99e891c586bd56aa41796abbe4ac3d8Chris Lattner sys::PrintStackTraceOnErrorSignal(); 138cc14d25dd99e891c586bd56aa41796abbe4ac3d8Chris Lattner PrettyStackTraceProgram X(argc, argv); 1397aa48441911e903803b75dfbcc148fbf80113819Michael J. Spencer 1400d7c695c74ae6d5f68cc07378c17491915e607d3Owen Anderson LLVMContext &Context = getGlobalContext(); 141cc14d25dd99e891c586bd56aa41796abbe4ac3d8Chris Lattner llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. 1427aa48441911e903803b75dfbcc148fbf80113819Michael J. Spencer 143ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Context.setDiagnosticHandler(diagnosticHandler, argv[0]); 1447aa48441911e903803b75dfbcc148fbf80113819Michael J. Spencer 14517e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner cl::ParseCommandLineOptions(argc, argv, "llvm .bc -> .ll disassembler\n"); 146009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 14717e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner std::string ErrorMessage; 14836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<Module> M; 149333fb04506233255f10d8095c9e2de5e5f0fdc6fMichael J. Spencer 1502ea93875b2f2900b9d244dfd7649c9ed02a34cd7Derek Schuff // Use the bitcode streaming interface 151ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DataStreamer *Streamer = getDataFileStreamer(InputFilename, &ErrorMessage); 152ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (Streamer) { 1532ea93875b2f2900b9d244dfd7649c9ed02a34cd7Derek Schuff std::string DisplayFilename; 1542ea93875b2f2900b9d244dfd7649c9ed02a34cd7Derek Schuff if (InputFilename == "-") 1552ea93875b2f2900b9d244dfd7649c9ed02a34cd7Derek Schuff DisplayFilename = "<stdin>"; 156c448aa66565252298028dec1a5fbc23ab6e24440Michael J. Spencer else 1572ea93875b2f2900b9d244dfd7649c9ed02a34cd7Derek Schuff DisplayFilename = InputFilename; 158ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ErrorOr<std::unique_ptr<Module>> MOrErr = 159ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines getStreamedBitcodeModule(DisplayFilename, Streamer, Context); 160ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines M = std::move(*MOrErr); 161ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines M->materializeAllPermanently(); 16217e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner } 1637aa48441911e903803b75dfbcc148fbf80113819Michael J. Spencer 16417e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner // Just use stdout. We won't actually print anything on it. 16517e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner if (DontPrint) 16617e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner OutputFilename = "-"; 1677aa48441911e903803b75dfbcc148fbf80113819Michael J. Spencer 16817e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner if (OutputFilename.empty()) { // Unspecified output, infer it. 16917e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner if (InputFilename == "-") { 17017e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner OutputFilename = "-"; 1711ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer } else { 17217e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner const std::string &IFN = InputFilename; 17317e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner int Len = IFN.length(); 17417e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner // If the source ends in .bc, strip it off. 17517e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner if (IFN[Len-3] == '.' && IFN[Len-2] == 'b' && IFN[Len-1] == 'c') 17617e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner OutputFilename = std::string(IFN.begin(), IFN.end()-3)+".ll"; 17717e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner else 17817e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner OutputFilename = IFN+".ll"; 1791ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer } 18017e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner } 181ec080467f5b322441055de1f6cd4f08edc23d7dfDan Gohman 18237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines std::error_code EC; 18336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<tool_output_file> Out( 18437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines new tool_output_file(OutputFilename, EC, sys::fs::F_None)); 18537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (EC) { 18637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines errs() << EC.message() << '\n'; 18717e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner return 1; 18817e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner } 1898f367bd3c0f56b7b318c46cee04f77735f617777Chris Lattner 19036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<AssemblyAnnotationWriter> Annotator; 1916cd71f0c4026217a501e09dcc2198c6c7a462e44Chris Lattner if (ShowAnnotations) 1926cd71f0c4026217a501e09dcc2198c6c7a462e44Chris Lattner Annotator.reset(new CommentWriter()); 1937aa48441911e903803b75dfbcc148fbf80113819Michael J. Spencer 19417e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner // All that llvm-dis does is write the assembly to a file. 19504fc8c8d335af7c54d9a4fb8409748d2c84402f3Dan Gohman if (!DontPrint) 1966cd71f0c4026217a501e09dcc2198c6c7a462e44Chris Lattner M->print(Out->os(), Annotator.get()); 197c30598bc3ad792eb8cc75b188eb872a28c62ab71Chris Lattner 198d5826a33a5a7c298a8934541d11cda042028be3bDan Gohman // Declare success. 199d5826a33a5a7c298a8934541d11cda042028be3bDan Gohman Out->keep(); 200d5826a33a5a7c298a8934541d11cda042028be3bDan Gohman 20117e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner return 0; 202009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner} 203