166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman//===-- llvm-objdump.cpp - Object file dumping utility for llvm -----------===//
266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman//
366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman//                     The LLVM Compiler Infrastructure
466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman//
566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// This file is distributed under the University of Illinois Open Source
666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// License. See LICENSE.TXT for details.
766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman//
866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman//===----------------------------------------------------------------------===//
966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman//
1066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// This program is a utility that works like binutils "objdump", that is, it
1166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// dumps out a plethora of information about an object file depending on the
1266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman// flags.
1366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman//
1466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman//===----------------------------------------------------------------------===//
1566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
1666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm-objdump.h"
1766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "MCFunction.h"
1866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/Object/Archive.h"
1966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/Object/ObjectFile.h"
2066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/ADT/OwningPtr.h"
2166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/ADT/Triple.h"
2266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/ADT/STLExtras.h"
2366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/MC/MCAsmInfo.h"
2466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/MC/MCDisassembler.h"
2566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/MC/MCInst.h"
2666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/MC/MCInstPrinter.h"
2766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/MC/MCSubtargetInfo.h"
2866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/Support/Casting.h"
2966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/Support/CommandLine.h"
3066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/Support/Debug.h"
3166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/Support/FileSystem.h"
3266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/Support/Format.h"
3366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/Support/GraphWriter.h"
3466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/Support/Host.h"
3566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/Support/ManagedStatic.h"
3666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/Support/MemoryBuffer.h"
3766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/Support/MemoryObject.h"
3866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/Support/PrettyStackTrace.h"
3966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/Support/Signals.h"
4066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/Support/SourceMgr.h"
4166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/Support/TargetRegistry.h"
4266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/Support/TargetSelect.h"
4366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/Support/raw_ostream.h"
4466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "llvm/Support/system_error.h"
4566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include <algorithm>
4666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include <cstring>
4766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanusing namespace llvm;
4866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanusing namespace object;
4966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
5066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstatic cl::list<std::string>
5166b8ab22586debccb1f787d4d52b7f042d4ddeb8John BaumanInputFilenames(cl::Positional, cl::desc("<input object files>"),cl::ZeroOrMore);
5266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
5366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstatic cl::opt<bool>
5466b8ab22586debccb1f787d4d52b7f042d4ddeb8John BaumanDisassemble("disassemble",
5566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  cl::desc("Display assembler mnemonics for the machine instructions"));
5666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstatic cl::alias
5766b8ab22586debccb1f787d4d52b7f042d4ddeb8John BaumanDisassembled("d", cl::desc("Alias for --disassemble"),
5866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman             cl::aliasopt(Disassemble));
5966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
6066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstatic cl::opt<bool>
6166b8ab22586debccb1f787d4d52b7f042d4ddeb8John BaumanRelocations("r", cl::desc("Display the relocation entries in the file"));
6266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
6366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstatic cl::opt<bool>
6466b8ab22586debccb1f787d4d52b7f042d4ddeb8John BaumanMachO("macho", cl::desc("Use MachO specific object file parser"));
6566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstatic cl::alias
6666b8ab22586debccb1f787d4d52b7f042d4ddeb8John BaumanMachOm("m", cl::desc("Alias for --macho"), cl::aliasopt(MachO));
6766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
6866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumancl::opt<std::string>
6966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanllvm::TripleName("triple", cl::desc("Target triple to disassemble for, "
7066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                    "see -version for available targets"));
7166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
7266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumancl::opt<std::string>
7366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanllvm::ArchName("arch", cl::desc("Target arch to disassemble for, "
7466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                "see -version for available targets"));
7566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
7666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstatic cl::opt<bool>
7766b8ab22586debccb1f787d4d52b7f042d4ddeb8John BaumanSectionHeaders("section-headers", cl::desc("Display summaries of the headers "
7866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                           "for each section."));
7966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstatic cl::alias
8066b8ab22586debccb1f787d4d52b7f042d4ddeb8John BaumanSectionHeadersShort("headers", cl::desc("Alias for --section-headers"),
8166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                    cl::aliasopt(SectionHeaders));
8266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstatic cl::alias
8366b8ab22586debccb1f787d4d52b7f042d4ddeb8John BaumanSectionHeadersShorter("h", cl::desc("Alias for --section-headers"),
8466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                      cl::aliasopt(SectionHeaders));
8566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
8666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstatic StringRef ToolName;
8766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
8866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstatic bool error(error_code ec) {
8966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  if (!ec) return false;
9066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
9166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  outs() << ToolName << ": error reading file: " << ec.message() << ".\n";
9266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  outs().flush();
9366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  return true;
9466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman}
9566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
9666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstatic const Target *GetTarget(const ObjectFile *Obj = NULL) {
9766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  // Figure out the target triple.
9866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  llvm::Triple TT("unknown-unknown-unknown");
9966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  if (TripleName.empty()) {
10066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    if (Obj)
10166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      TT.setArch(Triple::ArchType(Obj->getArch()));
10266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  } else
10366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    TT.setTriple(Triple::normalize(TripleName));
10466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
10566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  if (!ArchName.empty())
10666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    TT.setArchName(ArchName);
10766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
10866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  TripleName = TT.str();
10966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
11066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  // Get the target specific parser.
11166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  std::string Error;
11266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  const Target *TheTarget = TargetRegistry::lookupTarget(TripleName, Error);
11366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  if (TheTarget)
11466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    return TheTarget;
11566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
11666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  errs() << ToolName << ": error: unable to get target for '" << TripleName
11766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman         << "', see --version and --triple.\n";
11866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  return 0;
11966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman}
12066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
12166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanvoid llvm::DumpBytes(StringRef bytes) {
12266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  static const char hex_rep[] = "0123456789abcdef";
12366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  // FIXME: The real way to do this is to figure out the longest instruction
12466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  //        and align to that size before printing. I'll fix this when I get
12566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  //        around to outputting relocations.
12666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  // 15 is the longest x86 instruction
12766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  // 3 is for the hex rep of a byte + a space.
12866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  // 1 is for the null terminator.
12966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  enum { OutputSize = (15 * 3) + 1 };
13066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  char output[OutputSize];
13166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
13266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  assert(bytes.size() <= 15
13366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    && "DumpBytes only supports instructions of up to 15 bytes");
13466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  memset(output, ' ', sizeof(output));
13566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  unsigned index = 0;
13666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  for (StringRef::iterator i = bytes.begin(),
13766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                           e = bytes.end(); i != e; ++i) {
13866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    output[index] = hex_rep[(*i & 0xF0) >> 4];
13966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    output[index + 1] = hex_rep[*i & 0xF];
14066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    index += 3;
14166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  }
14266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
14366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  output[sizeof(output) - 1] = 0;
14466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  outs() << output;
14566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman}
14666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
14766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstatic bool RelocAddressLess(RelocationRef a, RelocationRef b) {
14866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  uint64_t a_addr, b_addr;
14966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  if (error(a.getAddress(a_addr))) return false;
15066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  if (error(b.getAddress(b_addr))) return false;
15166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  return a_addr < b_addr;
15266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman}
15366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
15466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstatic void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
15566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  const Target *TheTarget = GetTarget(Obj);
15666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  if (!TheTarget) {
15766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    // GetTarget prints out stuff.
15866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    return;
15966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  }
16066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
16166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  outs() << '\n';
16266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  outs() << Obj->getFileName()
16366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman         << ":\tfile format " << Obj->getFileFormatName() << "\n\n";
16466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
16566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  error_code ec;
16666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  for (section_iterator i = Obj->begin_sections(),
16766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                        e = Obj->end_sections();
16866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                        i != e; i.increment(ec)) {
16966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    if (error(ec)) break;
17066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    bool text;
17166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    if (error(i->isText(text))) break;
17266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    if (!text) continue;
17366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
17466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    uint64_t SectionAddr;
17566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    if (error(i->getAddress(SectionAddr))) break;
17666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
17766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    // Make a list of all the symbols in this section.
17866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    std::vector<std::pair<uint64_t, StringRef> > Symbols;
17966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    for (symbol_iterator si = Obj->begin_symbols(),
18066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                         se = Obj->end_symbols();
18166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                         si != se; si.increment(ec)) {
18266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      bool contains;
18366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      if (!error(i->containsSymbol(*si, contains)) && contains) {
18466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman        uint64_t Address;
18566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman        if (error(si->getOffset(Address))) break;
18666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman        StringRef Name;
18766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman        if (error(si->getName(Name))) break;
18866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman        Symbols.push_back(std::make_pair(Address, Name));
18966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      }
19066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    }
19166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
19266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    // Sort the symbols by address, just in case they didn't come in that way.
19366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    array_pod_sort(Symbols.begin(), Symbols.end());
19466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
19566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    // Make a list of all the relocations for this section.
19666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    std::vector<RelocationRef> Rels;
19766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    if (InlineRelocs) {
19866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      for (relocation_iterator ri = i->begin_relocations(),
19966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                               re = i->end_relocations();
20066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                              ri != re; ri.increment(ec)) {
20166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman        if (error(ec)) break;
20266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman        Rels.push_back(*ri);
20366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      }
20466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    }
20566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
20666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    // Sort relocations by address.
20766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    std::sort(Rels.begin(), Rels.end(), RelocAddressLess);
20866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
20966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    StringRef name;
21066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    if (error(i->getName(name))) break;
21166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    outs() << "Disassembly of section " << name << ':';
21266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
21366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    // If the section has no symbols just insert a dummy one and disassemble
21466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    // the whole section.
21566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    if (Symbols.empty())
21666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      Symbols.push_back(std::make_pair(0, name));
21766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
21866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    // Set up disassembler.
21966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    OwningPtr<const MCAsmInfo> AsmInfo(TheTarget->createMCAsmInfo(TripleName));
22066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
22166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    if (!AsmInfo) {
22266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      errs() << "error: no assembly info for target " << TripleName << "\n";
22366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      return;
22466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    }
22566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
22666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    OwningPtr<const MCSubtargetInfo> STI(
22766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      TheTarget->createMCSubtargetInfo(TripleName, "", ""));
22866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
22966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    if (!STI) {
23066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      errs() << "error: no subtarget info for target " << TripleName << "\n";
23166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      return;
23266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    }
23366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
23466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    OwningPtr<const MCDisassembler> DisAsm(
23566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      TheTarget->createMCDisassembler(*STI));
23666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    if (!DisAsm) {
23766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      errs() << "error: no disassembler for target " << TripleName << "\n";
23866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      return;
23966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    }
24066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
24166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    int AsmPrinterVariant = AsmInfo->getAssemblerDialect();
24266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    OwningPtr<MCInstPrinter> IP(TheTarget->createMCInstPrinter(
24366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                AsmPrinterVariant, *AsmInfo, *STI));
24466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    if (!IP) {
24566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      errs() << "error: no instruction printer for target " << TripleName
24666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman             << '\n';
24766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      return;
24866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    }
24966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
25066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    StringRef Bytes;
25166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    if (error(i->getContents(Bytes))) break;
25266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    StringRefMemoryObject memoryObject(Bytes);
25366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    uint64_t Size;
25466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    uint64_t Index;
25566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    uint64_t SectSize;
25666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    if (error(i->getSize(SectSize))) break;
25766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
25866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    std::vector<RelocationRef>::const_iterator rel_cur = Rels.begin();
25966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    std::vector<RelocationRef>::const_iterator rel_end = Rels.end();
26066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    // Disassemble symbol by symbol.
26166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    for (unsigned si = 0, se = Symbols.size(); si != se; ++si) {
26266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      uint64_t Start = Symbols[si].first;
26366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      uint64_t End;
26466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      // The end is either the size of the section or the beginning of the next
26566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      // symbol.
26666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      if (si == se - 1)
26766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman        End = SectSize;
26866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      // Make sure this symbol takes up space.
26966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      else if (Symbols[si + 1].first != Start)
27066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman        End = Symbols[si + 1].first - 1;
27166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      else
27266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman        // This symbol has the same address as the next symbol. Skip it.
27366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman        continue;
27466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
27566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      outs() << '\n' << Symbols[si].second << ":\n";
27666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
27766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#ifndef NDEBUG
27866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman        raw_ostream &DebugOut = DebugFlag ? dbgs() : nulls();
27966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#else
28066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman        raw_ostream &DebugOut = nulls();
28166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#endif
28266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
28366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      for (Index = Start; Index < End; Index += Size) {
28466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman        MCInst Inst;
28566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
28666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman        if (DisAsm->getInstruction(Inst, Size, memoryObject, Index,
28766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                   DebugOut, nulls())) {
28866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman          outs() << format("%8"PRIx64":\t", SectionAddr + Index);
28966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman          DumpBytes(StringRef(Bytes.data() + Index, Size));
29066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman          IP->printInst(&Inst, outs(), "");
29166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman          outs() << "\n";
29266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman        } else {
29366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman          errs() << ToolName << ": warning: invalid instruction encoding\n";
29466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman          if (Size == 0)
29566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman            Size = 1; // skip illegible bytes
29666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman        }
29766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
29866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman        // Print relocation for instruction.
29966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman        while (rel_cur != rel_end) {
30066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman          uint64_t addr;
30166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman          SmallString<16> name;
30266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman          SmallString<32> val;
30366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman          if (error(rel_cur->getAddress(addr))) goto skip_print_rel;
30466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman          // Stop when rel_cur's address is past the current instruction.
30566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman          if (addr > Index + Size) break;
30666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman          if (error(rel_cur->getTypeName(name))) goto skip_print_rel;
30766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman          if (error(rel_cur->getValueString(val))) goto skip_print_rel;
30866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
30966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman          outs() << format("\t\t\t%8"PRIx64": ", SectionAddr + addr) << name << "\t"
31066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                 << val << "\n";
31166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
31266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman        skip_print_rel:
31366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman          ++rel_cur;
31466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman        }
31566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      }
31666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    }
31766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  }
31866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman}
31966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
32066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstatic void PrintRelocations(const ObjectFile *o) {
32166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  error_code ec;
32266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  for (section_iterator si = o->begin_sections(), se = o->end_sections();
32366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                                  si != se; si.increment(ec)){
32466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    if (error(ec)) return;
32566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    if (si->begin_relocations() == si->end_relocations())
32666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      continue;
32766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    StringRef secname;
32866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    if (error(si->getName(secname))) continue;
32966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    outs() << "RELOCATION RECORDS FOR [" << secname << "]:\n";
33066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    for (relocation_iterator ri = si->begin_relocations(),
33166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                             re = si->end_relocations();
33266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                             ri != re; ri.increment(ec)) {
33366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      if (error(ec)) return;
33466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
33566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      uint64_t address;
33666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      SmallString<32> relocname;
33766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      SmallString<32> valuestr;
33866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      if (error(ri->getTypeName(relocname))) continue;
33966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      if (error(ri->getAddress(address))) continue;
34066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      if (error(ri->getValueString(valuestr))) continue;
34166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      outs() << address << " " << relocname << " " << valuestr << "\n";
34266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    }
34366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    outs() << "\n";
34466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  }
34566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman}
34666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
34766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstatic void PrintSectionHeaders(const ObjectFile *o) {
34866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  outs() << "Sections:\n"
34966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman            "Idx Name          Size      Address          Type\n";
35066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  error_code ec;
35166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  unsigned i = 0;
35266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  for (section_iterator si = o->begin_sections(), se = o->end_sections();
35366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                                                  si != se; si.increment(ec)) {
35466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    if (error(ec)) return;
35566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    StringRef Name;
35666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    if (error(si->getName(Name))) return;
35766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    uint64_t Address;
35866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    if (error(si->getAddress(Address))) return;
35966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    uint64_t Size;
36066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    if (error(si->getSize(Size))) return;
36166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    bool Text, Data, BSS;
36266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    if (error(si->isText(Text))) return;
36366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    if (error(si->isData(Data))) return;
36466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    if (error(si->isBSS(BSS))) return;
36566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    std::string Type = (std::string(Text ? "TEXT " : "") +
36666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                        (Data ? "DATA " : "") + (BSS ? "BSS" : ""));
36766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    outs() << format("%3d %-13s %09"PRIx64" %017"PRIx64" %s\n", i, Name.str().c_str(), Size,
36866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                     Address, Type.c_str());
36966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    ++i;
37066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  }
37166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman}
37266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
37366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstatic void DumpObject(const ObjectFile *o) {
37466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  if (Disassemble)
37566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    DisassembleObject(o, Relocations);
37666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  if (Relocations && !Disassemble)
37766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    PrintRelocations(o);
37866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  if (SectionHeaders)
37966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    PrintSectionHeaders(o);
38066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman}
38166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
38266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// @brief Dump each object file in \a a;
38366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstatic void DumpArchive(const Archive *a) {
38466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  for (Archive::child_iterator i = a->begin_children(),
38566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                               e = a->end_children(); i != e; ++i) {
38666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    OwningPtr<Binary> child;
38766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    if (error_code ec = i->getAsBinary(child)) {
38866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      errs() << ToolName << ": '" << a->getFileName() << "': " << ec.message()
38966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman             << ".\n";
39066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      continue;
39166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    }
39266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    if (ObjectFile *o = dyn_cast<ObjectFile>(child.get()))
39366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      DumpObject(o);
39466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    else
39566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman      errs() << ToolName << ": '" << a->getFileName() << "': "
39666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman              << "Unrecognized file type.\n";
39766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  }
39866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman}
39966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
40066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman/// @brief Open file and figure out how to dump it.
40166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstatic void DumpInput(StringRef file) {
40266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  // If file isn't stdin, check that it exists.
40366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  if (file != "-" && !sys::fs::exists(file)) {
40466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    errs() << ToolName << ": '" << file << "': " << "No such file\n";
40566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    return;
40666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  }
40766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
40866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  if (MachO && Disassemble) {
40966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    DisassembleInputMachO(file);
41066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    return;
41166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  }
41266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
41366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  // Attempt to open the binary.
41466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  OwningPtr<Binary> binary;
41566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  if (error_code ec = createBinary(file, binary)) {
41666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    errs() << ToolName << ": '" << file << "': " << ec.message() << ".\n";
41766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    return;
41866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  }
41966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
42066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  if (Archive *a = dyn_cast<Archive>(binary.get())) {
42166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    DumpArchive(a);
42266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  } else if (ObjectFile *o = dyn_cast<ObjectFile>(binary.get())) {
42366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    DumpObject(o);
42466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  } else {
42566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    errs() << ToolName << ": '" << file << "': " << "Unrecognized file type.\n";
42666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  }
42766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman}
42866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
42966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanint main(int argc, char **argv) {
43066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  // Print a stack trace if we signal out.
43166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  sys::PrintStackTraceOnErrorSignal();
43266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  PrettyStackTraceProgram X(argc, argv);
43366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.
43466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
43566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  // Initialize targets and assembly printers/parsers.
43666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  llvm::InitializeAllTargetInfos();
43766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  llvm::InitializeAllTargetMCs();
43866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  llvm::InitializeAllAsmParsers();
43966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  llvm::InitializeAllDisassemblers();
44066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
44166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  cl::ParseCommandLineOptions(argc, argv, "llvm object file dumper\n");
44266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  TripleName = Triple::normalize(TripleName);
44366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
44466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  ToolName = argv[0];
44566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
44666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  // Defaults to a.out if no filenames specified.
44766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  if (InputFilenames.size() == 0)
44866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    InputFilenames.push_back("a.out");
44966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
45066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  if (!Disassemble && !Relocations && !SectionHeaders) {
45166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    cl::PrintHelpMessage();
45266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    return 2;
45366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  }
45466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
45566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  std::for_each(InputFilenames.begin(), InputFilenames.end(),
45666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                DumpInput);
45766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
45866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman  return 0;
45966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman}
460