llvm-objdump.cpp revision 0b8b771e9f2f251460a6f200c45efe9d55640d60
192e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer//===-- llvm-objdump.cpp - Object file dumping utility for llvm -----------===//
292e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer//
392e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer//                     The LLVM Compiler Infrastructure
492e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer//
592e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer// This file is distributed under the University of Illinois Open Source
692e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer// License. See LICENSE.TXT for details.
792e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer//
892e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer//===----------------------------------------------------------------------===//
992e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer//
1092e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer// This program is a utility that works like binutils "objdump", that is, it
1192e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer// dumps out a plethora of information about an object file depending on the
1292e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer// flags.
1392e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer//
1492e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer//===----------------------------------------------------------------------===//
1592e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer
160b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include "llvm-objdump.h"
17685a2501b20baf688f6cc087f4b92bbafcd8028eBenjamin Kramer#include "MCFunction.h"
1892e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer#include "llvm/Object/ObjectFile.h"
1992e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer#include "llvm/ADT/OwningPtr.h"
2092e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer#include "llvm/ADT/Triple.h"
21739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer#include "llvm/ADT/STLExtras.h"
2292e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer#include "llvm/MC/MCAsmInfo.h"
2392e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer#include "llvm/MC/MCDisassembler.h"
2492e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer#include "llvm/MC/MCInst.h"
2592e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer#include "llvm/MC/MCInstPrinter.h"
267801136b95d1fbe515b9655b73ada39b05a33559Evan Cheng#include "llvm/MC/MCInstrAnalysis.h"
27685a2501b20baf688f6cc087f4b92bbafcd8028eBenjamin Kramer#include "llvm/MC/MCInstrDesc.h"
28685a2501b20baf688f6cc087f4b92bbafcd8028eBenjamin Kramer#include "llvm/MC/MCInstrInfo.h"
29b950585cc5a0d665e9accfe5ce490cd269756f2eJames Molloy#include "llvm/MC/MCSubtargetInfo.h"
3092e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer#include "llvm/Support/CommandLine.h"
3192e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer#include "llvm/Support/Debug.h"
3292e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer#include "llvm/Support/Format.h"
33853b0fd623491ef7dafeed20ee15897e3b95d82cBenjamin Kramer#include "llvm/Support/GraphWriter.h"
3492e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer#include "llvm/Support/Host.h"
3592e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer#include "llvm/Support/ManagedStatic.h"
3692e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer#include "llvm/Support/MemoryBuffer.h"
3792e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer#include "llvm/Support/MemoryObject.h"
3892e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer#include "llvm/Support/PrettyStackTrace.h"
3992e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer#include "llvm/Support/Signals.h"
4092e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer#include "llvm/Support/SourceMgr.h"
413e74d6fdd248e20a280f1dff3da9a6c689c2c4c3Evan Cheng#include "llvm/Support/TargetRegistry.h"
423e74d6fdd248e20a280f1dff3da9a6c689c2c4c3Evan Cheng#include "llvm/Support/TargetSelect.h"
4392e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer#include "llvm/Support/raw_ostream.h"
4492e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer#include "llvm/Support/system_error.h"
4592e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer#include <algorithm>
4692e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer#include <cstring>
4792e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencerusing namespace llvm;
4892e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencerusing namespace object;
4992e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer
500b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramerstatic cl::list<std::string>
510b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin KramerInputFilenames(cl::Positional, cl::desc("<input object files>"),cl::ZeroOrMore);
5292e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer
530b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramerstatic cl::opt<bool>
540b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin KramerDisassemble("disassemble",
550b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  cl::desc("Display assembler mnemonics for the machine instructions"));
560b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramerstatic cl::alias
570b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin KramerDisassembled("d", cl::desc("Alias for --disassemble"),
580b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer             cl::aliasopt(Disassemble));
5992e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer
600b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramerstatic cl::opt<bool>
610b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin KramerMachO("macho", cl::desc("Use MachO specific object file parser"));
620b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramerstatic cl::alias
630b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin KramerMachOm("m", cl::desc("Alias for --macho"), cl::aliasopt(MachO));
64685a2501b20baf688f6cc087f4b92bbafcd8028eBenjamin Kramer
650b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramercl::opt<std::string>
660b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramerllvm::TripleName("triple", cl::desc("Target triple to disassemble for, "
670b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer                                    "see -version for available targets"));
6892e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer
690b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramercl::opt<std::string>
700b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramerllvm::ArchName("arch", cl::desc("Target arch to disassemble for, "
710b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer                                "see -version for available targets"));
7292e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer
730b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramerstatic StringRef ToolName;
7425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer
750b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramerstatic bool error(error_code ec) {
760b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  if (!ec) return false;
7725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer
780b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  outs() << ToolName << ": error reading file: " << ec.message() << ".\n";
790b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  outs().flush();
800b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  return true;
8192e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer}
8292e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer
8392e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencerstatic const Target *GetTarget(const ObjectFile *Obj = NULL) {
8492e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  // Figure out the target triple.
8592e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  llvm::Triple TT("unknown-unknown-unknown");
86d11699d3c057129d0716fa548c67d1f62837f6b6Michael J. Spencer  if (TripleName.empty()) {
8792e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer    if (Obj)
8892e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer      TT.setArch(Triple::ArchType(Obj->getArch()));
89d11699d3c057129d0716fa548c67d1f62837f6b6Michael J. Spencer  } else
9092e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer    TT.setTriple(Triple::normalize(TripleName));
9192e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer
9292e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  if (!ArchName.empty())
9392e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer    TT.setArchName(ArchName);
9492e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer
9592e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  TripleName = TT.str();
9692e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer
9792e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  // Get the target specific parser.
9892e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  std::string Error;
9992e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  const Target *TheTarget = TargetRegistry::lookupTarget(TripleName, Error);
10092e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  if (TheTarget)
10192e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer    return TheTarget;
10292e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer
10392e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  errs() << ToolName << ": error: unable to get target for '" << TripleName
10492e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer         << "', see --version and --triple.\n";
10592e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  return 0;
10692e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer}
10792e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer
1080b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramervoid llvm::DumpBytes(StringRef bytes) {
1090b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  static const char hex_rep[] = "0123456789abcdef";
11092e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  // FIXME: The real way to do this is to figure out the longest instruction
11192e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  //        and align to that size before printing. I'll fix this when I get
11292e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  //        around to outputting relocations.
11392e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  // 15 is the longest x86 instruction
11492e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  // 3 is for the hex rep of a byte + a space.
11592e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  // 1 is for the null terminator.
11692e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  enum { OutputSize = (15 * 3) + 1 };
11792e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  char output[OutputSize];
11892e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer
11992e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  assert(bytes.size() <= 15
12092e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer    && "DumpBytes only supports instructions of up to 15 bytes");
12192e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  memset(output, ' ', sizeof(output));
12292e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  unsigned index = 0;
12392e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  for (StringRef::iterator i = bytes.begin(),
12492e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer                           e = bytes.end(); i != e; ++i) {
12592e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer    output[index] = hex_rep[(*i & 0xF0) >> 4];
12692e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer    output[index + 1] = hex_rep[*i & 0xF];
12792e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer    index += 3;
12892e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  }
12992e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer
13092e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  output[sizeof(output) - 1] = 0;
13192e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  outs() << output;
13292e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer}
13392e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer
1340b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramervoid llvm::DisassembleInputLibObject(StringRef Filename) {
13592e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  OwningPtr<MemoryBuffer> Buff;
13692e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer
13792e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  if (error_code ec = MemoryBuffer::getFileOrSTDIN(Filename, Buff)) {
13892e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer    errs() << ToolName << ": " << Filename << ": " << ec.message() << "\n";
13992e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer    return;
14092e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  }
14192e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer
14292e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  OwningPtr<ObjectFile> Obj(ObjectFile::createObjectFile(Buff.take()));
14392e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer
14492e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  const Target *TheTarget = GetTarget(Obj.get());
14592e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  if (!TheTarget) {
14692e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer    // GetTarget prints out stuff.
14792e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer    return;
14892e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  }
149685a2501b20baf688f6cc087f4b92bbafcd8028eBenjamin Kramer  const MCInstrInfo *InstrInfo = TheTarget->createMCInstrInfo();
15041ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramer  OwningPtr<MCInstrAnalysis>
15141ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramer    InstrAnalysis(TheTarget->createMCInstrAnalysis(InstrInfo));
15292e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer
15392e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  outs() << '\n';
15492e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  outs() << Filename
155739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer         << ":\tfile format " << Obj->getFileFormatName() << "\n\n";
15692e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer
15725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  error_code ec;
15892e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  for (ObjectFile::section_iterator i = Obj->begin_sections(),
15992e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer                                    e = Obj->end_sections();
16025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer                                    i != e; i.increment(ec)) {
16125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    if (error(ec)) break;
16225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    bool text;
16325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    if (error(i->isText(text))) break;
16425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    if (!text) continue;
16525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer
166739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer    // Make a list of all the symbols in this section.
167739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer    std::vector<std::pair<uint64_t, StringRef> > Symbols;
168739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer    for (ObjectFile::symbol_iterator si = Obj->begin_symbols(),
169739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer                                     se = Obj->end_symbols();
170739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer                                     si != se; si.increment(ec)) {
171739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer      bool contains;
172739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer      if (!error(i->containsSymbol(*si, contains)) && contains) {
173739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer        uint64_t Address;
174ac241fe9f0d73c6f632e4f7f89e06b698d39da54Benjamin Kramer        if (error(si->getOffset(Address))) break;
175739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer        StringRef Name;
176739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer        if (error(si->getName(Name))) break;
177739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer        Symbols.push_back(std::make_pair(Address, Name));
178739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer      }
179739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer    }
180739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer
181739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer    // Sort the symbols by address, just in case they didn't come in that way.
182739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer    array_pod_sort(Symbols.begin(), Symbols.end());
183739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer
18425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    StringRef name;
18525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    if (error(i->getName(name))) break;
186739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer    outs() << "Disassembly of section " << name << ':';
187739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer
188739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer    // If the section has no symbols just insert a dummy one and disassemble
189739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer    // the whole section.
190739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer    if (Symbols.empty())
191739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer      Symbols.push_back(std::make_pair(0, name));
19292e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer
19392e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer    // Set up disassembler.
1941abf2cb59b8d63415780a03329307c0997b2670cEvan Cheng    OwningPtr<const MCAsmInfo> AsmInfo(TheTarget->createMCAsmInfo(TripleName));
19592e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer
19692e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer    if (!AsmInfo) {
19792e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer      errs() << "error: no assembly info for target " << TripleName << "\n";
19892e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer      return;
19992e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer    }
20092e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer
201b950585cc5a0d665e9accfe5ce490cd269756f2eJames Molloy    OwningPtr<const MCSubtargetInfo> STI(TheTarget->createMCSubtargetInfo(TripleName, "", ""));
202b950585cc5a0d665e9accfe5ce490cd269756f2eJames Molloy
203b950585cc5a0d665e9accfe5ce490cd269756f2eJames Molloy    if (!STI) {
204b950585cc5a0d665e9accfe5ce490cd269756f2eJames Molloy      errs() << "error: no subtarget info for target " << TripleName << "\n";
205b950585cc5a0d665e9accfe5ce490cd269756f2eJames Molloy      return;
206b950585cc5a0d665e9accfe5ce490cd269756f2eJames Molloy    }
207b950585cc5a0d665e9accfe5ce490cd269756f2eJames Molloy
208b950585cc5a0d665e9accfe5ce490cd269756f2eJames Molloy    OwningPtr<const MCDisassembler> DisAsm(TheTarget->createMCDisassembler(*STI));
20992e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer    if (!DisAsm) {
21092e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer      errs() << "error: no disassembler for target " << TripleName << "\n";
21192e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer      return;
21292e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer    }
21392e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer
21492e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer    int AsmPrinterVariant = AsmInfo->getAssemblerDialect();
21592e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer    OwningPtr<MCInstPrinter> IP(TheTarget->createMCInstPrinter(
216b950585cc5a0d665e9accfe5ce490cd269756f2eJames Molloy                                AsmPrinterVariant, *AsmInfo, *STI));
21792e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer    if (!IP) {
21892e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer      errs() << "error: no instruction printer for target " << TripleName << '\n';
21992e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer      return;
22092e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer    }
22192e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer
22225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    StringRef Bytes;
22325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    if (error(i->getContents(Bytes))) break;
22492e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer    StringRefMemoryObject memoryObject(Bytes);
22592e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer    uint64_t Size;
22692e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer    uint64_t Index;
227739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer    uint64_t SectSize;
228739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer    if (error(i->getSize(SectSize))) break;
229739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer
230739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer    // Disassemble symbol by symbol.
231739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer    for (unsigned si = 0, se = Symbols.size(); si != se; ++si) {
232739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer      uint64_t Start = Symbols[si].first;
233739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer      uint64_t End = si == se-1 ? SectSize : Symbols[si + 1].first - 1;
234739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer      outs() << '\n' << Symbols[si].second << ":\n";
235739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer
236739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer#ifndef NDEBUG
237739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer        raw_ostream &DebugOut = DebugFlag ? dbgs() : nulls();
238739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer#else
239739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer        raw_ostream &DebugOut = nulls();
240739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer#endif
241739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer
2420b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer      for (Index = Start; Index < End; Index += Size) {
2430b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        MCInst Inst;
2440b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
2450b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        if (DisAsm->getInstruction(Inst, Size, memoryObject, Index,
2460b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer                                   DebugOut, nulls())) {
2470b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          uint64_t addr;
2480b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          if (error(i->getAddress(addr))) break;
2490b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          outs() << format("%8x:\t", addr + Index);
2500b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          DumpBytes(StringRef(Bytes.data() + Index, Size));
2510b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          IP->printInst(&Inst, outs(), "");
2520b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          outs() << "\n";
2530b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        } else {
2540b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          errs() << ToolName << ": warning: invalid instruction encoding\n";
2550b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          if (Size == 0)
2560b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer            Size = 1; // skip illegible bytes
257685a2501b20baf688f6cc087f4b92bbafcd8028eBenjamin Kramer        }
258685a2501b20baf688f6cc087f4b92bbafcd8028eBenjamin Kramer      }
25992e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer    }
26092e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  }
26192e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer}
26292e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer
26392e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencerint main(int argc, char **argv) {
26492e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  // Print a stack trace if we signal out.
26592e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  sys::PrintStackTraceOnErrorSignal();
26692e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  PrettyStackTraceProgram X(argc, argv);
26792e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.
26892e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer
26992e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  // Initialize targets and assembly printers/parsers.
27092e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  llvm::InitializeAllTargetInfos();
271e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng  llvm::InitializeAllTargetMCs();
27292e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  llvm::InitializeAllAsmParsers();
27392e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  llvm::InitializeAllDisassemblers();
27492e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer
27592e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  cl::ParseCommandLineOptions(argc, argv, "llvm object file dumper\n");
27692e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  TripleName = Triple::normalize(TripleName);
27792e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer
27892e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  ToolName = argv[0];
27992e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer
28092e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  // Defaults to a.out if no filenames specified.
28192e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  if (InputFilenames.size() == 0)
28292e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer    InputFilenames.push_back("a.out");
28392e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer
28492e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  // -d is the only flag that is currently implemented, so just print help if
28592e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  // it is not set.
28692e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  if (!Disassemble) {
28792e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer    cl::PrintHelpMessage();
28892e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer    return 2;
28992e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  }
29092e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer
2910b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  if (MachO)
2920b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    std::for_each(InputFilenames.begin(), InputFilenames.end(),
2930b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer                  DisassembleInputMachO);
2940b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  else
2950b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    std::for_each(InputFilenames.begin(), InputFilenames.end(),
2960b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer                  DisassembleInputLibObject);
29792e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer
29892e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  return 0;
29992e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer}
300