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//
14dd3aa9eab2b40ea1573a5482472bbb89e6f1038dMichael J. Spencer// The flags and output of this program should be near identical to those of
15dd3aa9eab2b40ea1573a5482472bbb89e6f1038dMichael J. Spencer// binutils objdump.
16dd3aa9eab2b40ea1573a5482472bbb89e6f1038dMichael J. Spencer//
1792e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer//===----------------------------------------------------------------------===//
1892e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer
190b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include "llvm-objdump.h"
20f010c464a11444733ec67e31aace8bcebeaf2588Chandler Carruth#include "llvm/ADT/STLExtras.h"
211e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer#include "llvm/ADT/StringExtras.h"
2292e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer#include "llvm/ADT/Triple.h"
2392e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer#include "llvm/MC/MCAsmInfo.h"
242c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha#include "llvm/MC/MCContext.h"
2592e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer#include "llvm/MC/MCDisassembler.h"
2692e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer#include "llvm/MC/MCInst.h"
2792e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer#include "llvm/MC/MCInstPrinter.h"
28ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha#include "llvm/MC/MCInstrAnalysis.h"
2917463b3ef1a3d39b10619254f12e806c8c43f9e7Craig Topper#include "llvm/MC/MCInstrInfo.h"
302c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha#include "llvm/MC/MCObjectFileInfo.h"
31c6449b636f4984be88f128d0375c056ad05e7e8fJim Grosbach#include "llvm/MC/MCRegisterInfo.h"
322c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha#include "llvm/MC/MCRelocationInfo.h"
33ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha#include "llvm/MC/MCSubtargetInfo.h"
34f010c464a11444733ec67e31aace8bcebeaf2588Chandler Carruth#include "llvm/Object/Archive.h"
35f010c464a11444733ec67e31aace8bcebeaf2588Chandler Carruth#include "llvm/Object/COFF.h"
36cef81b37c77978cd4dddb4a5ad13564793ded155Rafael Espindola#include "llvm/Object/MachO.h"
37f010c464a11444733ec67e31aace8bcebeaf2588Chandler Carruth#include "llvm/Object/ObjectFile.h"
3827781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer#include "llvm/Support/Casting.h"
3992e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer#include "llvm/Support/CommandLine.h"
4092e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer#include "llvm/Support/Debug.h"
4127781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer#include "llvm/Support/FileSystem.h"
4292e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer#include "llvm/Support/Format.h"
43853b0fd623491ef7dafeed20ee15897e3b95d82cBenjamin Kramer#include "llvm/Support/GraphWriter.h"
4492e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer#include "llvm/Support/Host.h"
4592e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer#include "llvm/Support/ManagedStatic.h"
4692e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer#include "llvm/Support/MemoryBuffer.h"
4792e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer#include "llvm/Support/PrettyStackTrace.h"
4892e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer#include "llvm/Support/Signals.h"
4992e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer#include "llvm/Support/SourceMgr.h"
503e74d6fdd248e20a280f1dff3da9a6c689c2c4c3Evan Cheng#include "llvm/Support/TargetRegistry.h"
513e74d6fdd248e20a280f1dff3da9a6c689c2c4c3Evan Cheng#include "llvm/Support/TargetSelect.h"
5292e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer#include "llvm/Support/raw_ostream.h"
5392e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer#include <algorithm>
5481bbdfda82a3e5528d979b2cc150e9c7e0fa4427Benjamin Kramer#include <cctype>
5592e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer#include <cstring>
56c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines#include <system_error>
57171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha
5892e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencerusing namespace llvm;
5992e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencerusing namespace object;
6092e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer
610b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramerstatic cl::list<std::string>
620b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin KramerInputFilenames(cl::Positional, cl::desc("<input object files>"),cl::ZeroOrMore);
6392e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer
64ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinescl::opt<bool>
65ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesllvm::Disassemble("disassemble",
660b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  cl::desc("Display assembler mnemonics for the machine instructions"));
670b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramerstatic cl::alias
680b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin KramerDisassembled("d", cl::desc("Alias for --disassemble"),
690b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer             cl::aliasopt(Disassemble));
7092e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer
71ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinescl::opt<bool>
72ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesllvm::Relocations("r", cl::desc("Display the relocation entries in the file"));
7327781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer
74ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinescl::opt<bool>
75ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesllvm::SectionContents("s", cl::desc("Display the content of each section"));
761e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer
77ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinescl::opt<bool>
78ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesllvm::SymbolTable("t", cl::desc("Display the symbol table"));
7922ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencer
80ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinescl::opt<bool>
81ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesllvm::ExportsTrie("exports-trie", cl::desc("Display mach-o exported symbols"));
8237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
83ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinescl::opt<bool>
84ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesllvm::Rebase("rebase", cl::desc("Display mach-o rebasing info"));
8537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
86ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinescl::opt<bool>
87ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesllvm::Bind("bind", cl::desc("Display mach-o binding info"));
8837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
89ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinescl::opt<bool>
90ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesllvm::LazyBind("lazy-bind", cl::desc("Display mach-o lazy binding info"));
9137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
92ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinescl::opt<bool>
93ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesllvm::WeakBind("weak-bind", cl::desc("Display mach-o weak binding info"));
9437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
9537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic cl::opt<bool>
96cef81b37c77978cd4dddb4a5ad13564793ded155Rafael EspindolaMachOOpt("macho", cl::desc("Use MachO specific object file parser"));
970b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramerstatic cl::alias
98cef81b37c77978cd4dddb4a5ad13564793ded155Rafael EspindolaMachOm("m", cl::desc("Alias for --macho"), cl::aliasopt(MachOOpt));
99685a2501b20baf688f6cc087f4b92bbafcd8028eBenjamin Kramer
1000b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramercl::opt<std::string>
1010b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramerllvm::TripleName("triple", cl::desc("Target triple to disassemble for, "
1020b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer                                    "see -version for available targets"));
10392e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer
1040b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramercl::opt<std::string>
10537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesllvm::MCPU("mcpu",
10637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines     cl::desc("Target a specific cpu type (-mcpu=help for details)"),
10737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines     cl::value_desc("cpu-name"),
10837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines     cl::init(""));
10937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
11037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinescl::opt<std::string>
111ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesllvm::ArchName("arch-name", cl::desc("Target arch to disassemble for, "
1120b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer                                "see -version for available targets"));
11392e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer
114ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinescl::opt<bool>
115ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesllvm::SectionHeaders("section-headers", cl::desc("Display summaries of the "
116ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                                 "headers for each section."));
117023bb15beaac3744ce3a5d1f750d6e32829c7130Nick Lewyckystatic cl::alias
118023bb15beaac3744ce3a5d1f750d6e32829c7130Nick LewyckySectionHeadersShort("headers", cl::desc("Alias for --section-headers"),
119023bb15beaac3744ce3a5d1f750d6e32829c7130Nick Lewycky                    cl::aliasopt(SectionHeaders));
120023bb15beaac3744ce3a5d1f750d6e32829c7130Nick Lewyckystatic cl::alias
121023bb15beaac3744ce3a5d1f750d6e32829c7130Nick LewyckySectionHeadersShorter("h", cl::desc("Alias for --section-headers"),
122023bb15beaac3744ce3a5d1f750d6e32829c7130Nick Lewycky                      cl::aliasopt(SectionHeaders));
123023bb15beaac3744ce3a5d1f750d6e32829c7130Nick Lewycky
12437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinescl::list<std::string>
12537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesllvm::MAttrs("mattr",
126fd6d1651551d5a08b3cf0fcafed5e91a40b8e317Jack Carter  cl::CommaSeparated,
127fd6d1651551d5a08b3cf0fcafed5e91a40b8e317Jack Carter  cl::desc("Target specific attributes"),
128fd6d1651551d5a08b3cf0fcafed5e91a40b8e317Jack Carter  cl::value_desc("a1,+a2,-a3,..."));
129fd6d1651551d5a08b3cf0fcafed5e91a40b8e317Jack Carter
13037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinescl::opt<bool>
13137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesllvm::NoShowRawInsn("no-show-raw-insn", cl::desc("When disassembling "
13237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                                 "instructions, do not print "
13337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                                 "the instruction bytes."));
1348b9da530e3637fd4afb33f80673178dcc74397f0Eli Bendersky
135ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinescl::opt<bool>
136ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesllvm::UnwindInfo("unwind-info", cl::desc("Display unwind information"));
137eef7b6219ebe5d0ded0be4adb3003055fa8a63c4Michael J. Spencer
138eef7b6219ebe5d0ded0be4adb3003055fa8a63c4Michael J. Spencerstatic cl::alias
139eef7b6219ebe5d0ded0be4adb3003055fa8a63c4Michael J. SpencerUnwindInfoShort("u", cl::desc("Alias for --unwind-info"),
140eef7b6219ebe5d0ded0be4adb3003055fa8a63c4Michael J. Spencer                cl::aliasopt(UnwindInfo));
141eef7b6219ebe5d0ded0be4adb3003055fa8a63c4Michael J. Spencer
142ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinescl::opt<bool>
143ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesllvm::PrivateHeaders("private-headers",
144ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                     cl::desc("Display format specific file headers"));
145b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer
146b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencerstatic cl::alias
147b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. SpencerPrivateHeadersShort("p", cl::desc("Alias for --private-headers"),
148b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer                    cl::aliasopt(PrivateHeaders));
149b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer
1500b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramerstatic StringRef ToolName;
151ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic int ReturnValue = EXIT_SUCCESS;
15225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer
153c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesbool llvm::error(std::error_code EC) {
15436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (!EC)
15536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
15625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer
15736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  outs() << ToolName << ": error reading file: " << EC.message() << ".\n";
1580b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  outs().flush();
159ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  ReturnValue = EXIT_FAILURE;
1600b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  return true;
16192e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer}
16292e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer
163dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic const Target *getTarget(const ObjectFile *Obj = nullptr) {
16492e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  // Figure out the target triple.
1659ed9e5d0f994c7721185eba963ea9b907dabcde6Kevin Enderby  llvm::Triple TheTriple("unknown-unknown-unknown");
166d11699d3c057129d0716fa548c67d1f62837f6b6Michael J. Spencer  if (TripleName.empty()) {
1672c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha    if (Obj) {
1689ed9e5d0f994c7721185eba963ea9b907dabcde6Kevin Enderby      TheTriple.setArch(Triple::ArchType(Obj->getArch()));
1692c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha      // TheTriple defaults to ELF, and COFF doesn't have an environment:
1702c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha      // the best we can do here is indicate that it is mach-o.
1712c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha      if (Obj->isMachO())
17236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        TheTriple.setObjectFormat(Triple::MachO);
173dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
174dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (Obj->isCOFF()) {
175dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        const auto COFFObj = dyn_cast<COFFObjectFile>(Obj);
176dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        if (COFFObj->getArch() == Triple::thumb)
177dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          TheTriple.setTriple("thumbv7-windows");
178dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      }
1792c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha    }
180d11699d3c057129d0716fa548c67d1f62837f6b6Michael J. Spencer  } else
1819ed9e5d0f994c7721185eba963ea9b907dabcde6Kevin Enderby    TheTriple.setTriple(Triple::normalize(TripleName));
18292e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer
18392e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  // Get the target specific parser.
18492e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  std::string Error;
1859ed9e5d0f994c7721185eba963ea9b907dabcde6Kevin Enderby  const Target *TheTarget = TargetRegistry::lookupTarget(ArchName, TheTriple,
1869ed9e5d0f994c7721185eba963ea9b907dabcde6Kevin Enderby                                                         Error);
1879ed9e5d0f994c7721185eba963ea9b907dabcde6Kevin Enderby  if (!TheTarget) {
1889ed9e5d0f994c7721185eba963ea9b907dabcde6Kevin Enderby    errs() << ToolName << ": " << Error;
189dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return nullptr;
1909ed9e5d0f994c7721185eba963ea9b907dabcde6Kevin Enderby  }
1919ed9e5d0f994c7721185eba963ea9b907dabcde6Kevin Enderby
1929ed9e5d0f994c7721185eba963ea9b907dabcde6Kevin Enderby  // Update the triple name and return the found target.
1939ed9e5d0f994c7721185eba963ea9b907dabcde6Kevin Enderby  TripleName = TheTriple.getTriple();
1949ed9e5d0f994c7721185eba963ea9b907dabcde6Kevin Enderby  return TheTarget;
19592e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer}
19692e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer
1974c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarvoid llvm::DumpBytes(ArrayRef<uint8_t> bytes) {
1980b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  static const char hex_rep[] = "0123456789abcdef";
1994c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  SmallString<64> output;
2004c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar
2014c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  for (char i: bytes) {
2024c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    output.push_back(hex_rep[(i & 0xF0) >> 4]);
2034c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    output.push_back(hex_rep[i & 0xF]);
2044c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    output.push_back(' ');
20592e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  }
20692e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer
2074c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  outs() << output.c_str();
20892e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer}
20992e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer
210eef7b6219ebe5d0ded0be4adb3003055fa8a63c4Michael J. Spencerbool llvm::RelocAddressLess(RelocationRef a, RelocationRef b) {
211942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer  uint64_t a_addr, b_addr;
212956ca7265c697107708468b7e1b2fd21f4185baeRafael Espindola  if (error(a.getOffset(a_addr))) return false;
213956ca7265c697107708468b7e1b2fd21f4185baeRafael Espindola  if (error(b.getOffset(b_addr))) return false;
214942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer  return a_addr < b_addr;
215942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer}
216942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer
217942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencerstatic void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
2183f5d1a2396915ebff20ce4f5d668ee5c839d1d91Jim Grosbach  const Target *TheTarget = getTarget(Obj);
2193f5d1a2396915ebff20ce4f5d668ee5c839d1d91Jim Grosbach  // getTarget() will have already issued a diagnostic if necessary, so
2203f5d1a2396915ebff20ce4f5d668ee5c839d1d91Jim Grosbach  // just bail here if it failed.
2213f5d1a2396915ebff20ce4f5d668ee5c839d1d91Jim Grosbach  if (!TheTarget)
22292e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer    return;
22392e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer
224fd6d1651551d5a08b3cf0fcafed5e91a40b8e317Jack Carter  // Package up features to be passed to target/subtarget
225fd6d1651551d5a08b3cf0fcafed5e91a40b8e317Jack Carter  std::string FeaturesStr;
226fd6d1651551d5a08b3cf0fcafed5e91a40b8e317Jack Carter  if (MAttrs.size()) {
227fd6d1651551d5a08b3cf0fcafed5e91a40b8e317Jack Carter    SubtargetFeatures Features;
228fd6d1651551d5a08b3cf0fcafed5e91a40b8e317Jack Carter    for (unsigned i = 0; i != MAttrs.size(); ++i)
229fd6d1651551d5a08b3cf0fcafed5e91a40b8e317Jack Carter      Features.AddFeature(MAttrs[i]);
230fd6d1651551d5a08b3cf0fcafed5e91a40b8e317Jack Carter    FeaturesStr = Features.getString();
231fd6d1651551d5a08b3cf0fcafed5e91a40b8e317Jack Carter  }
232fd6d1651551d5a08b3cf0fcafed5e91a40b8e317Jack Carter
23336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  std::unique_ptr<const MCRegisterInfo> MRI(
23436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      TheTarget->createMCRegInfo(TripleName));
23527a33ad5ce3a6ca9a5d7546b41d96e975b1e9305Ahmed Bougacha  if (!MRI) {
23627a33ad5ce3a6ca9a5d7546b41d96e975b1e9305Ahmed Bougacha    errs() << "error: no register info for target " << TripleName << "\n";
23727a33ad5ce3a6ca9a5d7546b41d96e975b1e9305Ahmed Bougacha    return;
23827a33ad5ce3a6ca9a5d7546b41d96e975b1e9305Ahmed Bougacha  }
23927a33ad5ce3a6ca9a5d7546b41d96e975b1e9305Ahmed Bougacha
24027a33ad5ce3a6ca9a5d7546b41d96e975b1e9305Ahmed Bougacha  // Set up disassembler.
24136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  std::unique_ptr<const MCAsmInfo> AsmInfo(
24236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      TheTarget->createMCAsmInfo(*MRI, TripleName));
24327a33ad5ce3a6ca9a5d7546b41d96e975b1e9305Ahmed Bougacha  if (!AsmInfo) {
24427a33ad5ce3a6ca9a5d7546b41d96e975b1e9305Ahmed Bougacha    errs() << "error: no assembly info for target " << TripleName << "\n";
24527a33ad5ce3a6ca9a5d7546b41d96e975b1e9305Ahmed Bougacha    return;
24627a33ad5ce3a6ca9a5d7546b41d96e975b1e9305Ahmed Bougacha  }
24727a33ad5ce3a6ca9a5d7546b41d96e975b1e9305Ahmed Bougacha
24836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  std::unique_ptr<const MCSubtargetInfo> STI(
24937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      TheTarget->createMCSubtargetInfo(TripleName, MCPU, FeaturesStr));
25027a33ad5ce3a6ca9a5d7546b41d96e975b1e9305Ahmed Bougacha  if (!STI) {
25127a33ad5ce3a6ca9a5d7546b41d96e975b1e9305Ahmed Bougacha    errs() << "error: no subtarget info for target " << TripleName << "\n";
25227a33ad5ce3a6ca9a5d7546b41d96e975b1e9305Ahmed Bougacha    return;
25327a33ad5ce3a6ca9a5d7546b41d96e975b1e9305Ahmed Bougacha  }
25427a33ad5ce3a6ca9a5d7546b41d96e975b1e9305Ahmed Bougacha
25536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  std::unique_ptr<const MCInstrInfo> MII(TheTarget->createMCInstrInfo());
2562c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha  if (!MII) {
2572c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha    errs() << "error: no instruction info for target " << TripleName << "\n";
2582c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha    return;
2592c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha  }
2602c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha
261dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  std::unique_ptr<const MCObjectFileInfo> MOFI(new MCObjectFileInfo);
262dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MCContext Ctx(AsmInfo.get(), MRI.get(), MOFI.get());
263dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
264dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  std::unique_ptr<MCDisassembler> DisAsm(
265dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    TheTarget->createMCDisassembler(*STI, Ctx));
266dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
26727a33ad5ce3a6ca9a5d7546b41d96e975b1e9305Ahmed Bougacha  if (!DisAsm) {
26827a33ad5ce3a6ca9a5d7546b41d96e975b1e9305Ahmed Bougacha    errs() << "error: no disassembler for target " << TripleName << "\n";
26927a33ad5ce3a6ca9a5d7546b41d96e975b1e9305Ahmed Bougacha    return;
27027a33ad5ce3a6ca9a5d7546b41d96e975b1e9305Ahmed Bougacha  }
27127a33ad5ce3a6ca9a5d7546b41d96e975b1e9305Ahmed Bougacha
27236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  std::unique_ptr<const MCInstrAnalysis> MIA(
27336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      TheTarget->createMCInstrAnalysis(MII.get()));
274ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha
27527a33ad5ce3a6ca9a5d7546b41d96e975b1e9305Ahmed Bougacha  int AsmPrinterVariant = AsmInfo->getAssemblerDialect();
27636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  std::unique_ptr<MCInstPrinter> IP(TheTarget->createMCInstPrinter(
2772c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar      Triple(TripleName), AsmPrinterVariant, *AsmInfo, *MII, *MRI));
27827a33ad5ce3a6ca9a5d7546b41d96e975b1e9305Ahmed Bougacha  if (!IP) {
27927a33ad5ce3a6ca9a5d7546b41d96e975b1e9305Ahmed Bougacha    errs() << "error: no instruction printer for target " << TripleName
28027a33ad5ce3a6ca9a5d7546b41d96e975b1e9305Ahmed Bougacha      << '\n';
28127a33ad5ce3a6ca9a5d7546b41d96e975b1e9305Ahmed Bougacha    return;
28227a33ad5ce3a6ca9a5d7546b41d96e975b1e9305Ahmed Bougacha  }
28327a33ad5ce3a6ca9a5d7546b41d96e975b1e9305Ahmed Bougacha
28436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  StringRef Fmt = Obj->getBytesInAddress() > 4 ? "\t\t%016" PRIx64 ":  " :
28536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                                 "\t\t\t%08" PRIx64 ":  ";
28636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
28736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Create a mapping, RelocSecs = SectionRelocMap[S], where sections
28836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // in RelocSecs contain the relocations for section S.
289c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  std::error_code EC;
29036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  std::map<SectionRef, SmallVector<SectionRef, 1>> SectionRelocMap;
29136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  for (const SectionRef &Section : Obj->sections()) {
29236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    section_iterator Sec2 = Section.getRelocatedSection();
29336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (Sec2 != Obj->section_end())
29436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      SectionRelocMap[*Sec2].push_back(Section);
29536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
296ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha
29736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  for (const SectionRef &Section : Obj->sections()) {
29837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (!Section.isText() || Section.isVirtual())
29936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      continue;
30025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer
30137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint64_t SectionAddr = Section.getAddress();
30237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint64_t SectSize = Section.getSize();
30337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (!SectSize)
30437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      continue;
305942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer
306739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer    // Make a list of all the symbols in this section.
30736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    std::vector<std::pair<uint64_t, StringRef>> Symbols;
30836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    for (const SymbolRef &Symbol : Obj->symbols()) {
30937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      if (Section.containsSymbol(Symbol)) {
310739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer        uint64_t Address;
31136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        if (error(Symbol.getAddress(Address)))
31236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          break;
31336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        if (Address == UnknownAddressOrSize)
31436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          continue;
315aab219110994cc4d848fae5f50166a2f70ccc812Cameron Zwarich        Address -= SectionAddr;
31636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        if (Address >= SectSize)
31736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          continue;
318aab219110994cc4d848fae5f50166a2f70ccc812Cameron Zwarich
319739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer        StringRef Name;
32036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        if (error(Symbol.getName(Name)))
32136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          break;
322739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer        Symbols.push_back(std::make_pair(Address, Name));
323739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer      }
324739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer    }
325739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer
326739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer    // Sort the symbols by address, just in case they didn't come in that way.
327739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer    array_pod_sort(Symbols.begin(), Symbols.end());
328739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer
329942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer    // Make a list of all the relocations for this section.
330942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer    std::vector<RelocationRef> Rels;
331942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer    if (InlineRelocs) {
33236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      for (const SectionRef &RelocSec : SectionRelocMap[Section]) {
33336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        for (const RelocationRef &Reloc : RelocSec.relocations()) {
33436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          Rels.push_back(Reloc);
33536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        }
336942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer      }
337942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer    }
338942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer
339942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer    // Sort relocations by address.
340942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer    std::sort(Rels.begin(), Rels.end(), RelocAddressLess);
341942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer
342cef81b37c77978cd4dddb4a5ad13564793ded155Rafael Espindola    StringRef SegmentName = "";
34336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (const MachOObjectFile *MachO = dyn_cast<const MachOObjectFile>(Obj)) {
34436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      DataRefImpl DR = Section.getRawDataRefImpl();
345fd7aa38e304a09fa0ef51b85b773b649b7e58c5eRafael Espindola      SegmentName = MachO->getSectionFinalSegmentName(DR);
346cef81b37c77978cd4dddb4a5ad13564793ded155Rafael Espindola    }
34725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    StringRef name;
34836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (error(Section.getName(name)))
34936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      break;
350cef81b37c77978cd4dddb4a5ad13564793ded155Rafael Espindola    outs() << "Disassembly of section ";
351cef81b37c77978cd4dddb4a5ad13564793ded155Rafael Espindola    if (!SegmentName.empty())
352cef81b37c77978cd4dddb4a5ad13564793ded155Rafael Espindola      outs() << SegmentName << ",";
353cef81b37c77978cd4dddb4a5ad13564793ded155Rafael Espindola    outs() << name << ':';
354739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer
355739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer    // If the section has no symbols just insert a dummy one and disassemble
356739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer    // the whole section.
357739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer    if (Symbols.empty())
358739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer      Symbols.push_back(std::make_pair(0, name));
35992e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer
3602c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha
3612c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha    SmallString<40> Comments;
3622c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha    raw_svector_ostream CommentStream(Comments);
3632c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha
36437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    StringRef BytesStr;
36537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (error(Section.getContents(BytesStr)))
36636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      break;
36737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    ArrayRef<uint8_t> Bytes(reinterpret_cast<const uint8_t *>(BytesStr.data()),
36837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                            BytesStr.size());
36937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
37092e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer    uint64_t Size;
37192e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer    uint64_t Index;
372739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer
373942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer    std::vector<RelocationRef>::const_iterator rel_cur = Rels.begin();
374942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer    std::vector<RelocationRef>::const_iterator rel_end = Rels.end();
375739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer    // Disassemble symbol by symbol.
376739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer    for (unsigned si = 0, se = Symbols.size(); si != se; ++si) {
37737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
378739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer      uint64_t Start = Symbols[si].first;
37937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      // The end is either the section end or the beginning of the next symbol.
38037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      uint64_t End = (si == se - 1) ? SectSize : Symbols[si + 1].first;
38137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      // If this symbol has the same address as the next symbol, then skip it.
38237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      if (Start == End)
383178dbd44187e23e7e3f3ba17b00c89c819070296Michael J. Spencer        continue;
384178dbd44187e23e7e3f3ba17b00c89c819070296Michael J. Spencer
385739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer      outs() << '\n' << Symbols[si].second << ":\n";
386739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer
387739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer#ifndef NDEBUG
38836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      raw_ostream &DebugOut = DebugFlag ? dbgs() : nulls();
389739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer#else
39036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      raw_ostream &DebugOut = nulls();
391739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer#endif
392739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer
3930b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer      for (Index = Start; Index < End; Index += Size) {
3940b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        MCInst Inst;
3950b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
39637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        if (DisAsm->getInstruction(Inst, Size, Bytes.slice(Index),
39737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                   SectionAddr + Index, DebugOut,
39837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                   CommentStream)) {
3998b9da530e3637fd4afb33f80673178dcc74397f0Eli Bendersky          outs() << format("%8" PRIx64 ":", SectionAddr + Index);
4008b9da530e3637fd4afb33f80673178dcc74397f0Eli Bendersky          if (!NoShowRawInsn) {
4018b9da530e3637fd4afb33f80673178dcc74397f0Eli Bendersky            outs() << "\t";
4024c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar            DumpBytes(ArrayRef<uint8_t>(Bytes.data() + Index, Size));
4038b9da530e3637fd4afb33f80673178dcc74397f0Eli Bendersky          }
4042c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar          IP->printInst(&Inst, outs(), "", *STI);
4052c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha          outs() << CommentStream.str();
4062c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha          Comments.clear();
4070b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          outs() << "\n";
4080b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        } else {
4090b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          errs() << ToolName << ": warning: invalid instruction encoding\n";
4100b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          if (Size == 0)
4110b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer            Size = 1; // skip illegible bytes
412685a2501b20baf688f6cc087f4b92bbafcd8028eBenjamin Kramer        }
413942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer
414942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer        // Print relocation for instruction.
415942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer        while (rel_cur != rel_end) {
4160685e94895f26f96aa1032696e3150dd00aad1f3Owen Anderson          bool hidden = false;
417942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer          uint64_t addr;
418942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer          SmallString<16> name;
419942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer          SmallString<32> val;
4200685e94895f26f96aa1032696e3150dd00aad1f3Owen Anderson
4210685e94895f26f96aa1032696e3150dd00aad1f3Owen Anderson          // If this relocation is hidden, skip it.
4220685e94895f26f96aa1032696e3150dd00aad1f3Owen Anderson          if (error(rel_cur->getHidden(hidden))) goto skip_print_rel;
4230685e94895f26f96aa1032696e3150dd00aad1f3Owen Anderson          if (hidden) goto skip_print_rel;
4240685e94895f26f96aa1032696e3150dd00aad1f3Owen Anderson
425956ca7265c697107708468b7e1b2fd21f4185baeRafael Espindola          if (error(rel_cur->getOffset(addr))) goto skip_print_rel;
426942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer          // Stop when rel_cur's address is past the current instruction.
42734749ce4df9636188782c652dc9dc9c73d4bce11Owen Anderson          if (addr >= Index + Size) break;
428942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer          if (error(rel_cur->getTypeName(name))) goto skip_print_rel;
429942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer          if (error(rel_cur->getValueString(val))) goto skip_print_rel;
430942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer
43136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          outs() << format(Fmt.data(), SectionAddr + addr) << name
43251cf8661637c114e4b4f178bd2677a6bb246be0dBenjamin Kramer                 << "\t" << val << "\n";
433942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer
434942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer        skip_print_rel:
435942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer          ++rel_cur;
436942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer        }
437685a2501b20baf688f6cc087f4b92bbafcd8028eBenjamin Kramer      }
43892e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer    }
43992e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  }
44092e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer}
44192e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer
442ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesvoid llvm::PrintRelocations(const ObjectFile *Obj) {
44336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  StringRef Fmt = Obj->getBytesInAddress() > 4 ? "%016" PRIx64 :
44436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                                 "%08" PRIx64;
44537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // Regular objdump doesn't print relocations in non-relocatable object
44637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // files.
44737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (!Obj->isRelocatableObject())
44837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return;
44937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
45036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  for (const SectionRef &Section : Obj->sections()) {
45136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (Section.relocation_begin() == Section.relocation_end())
45227781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer      continue;
45327781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer    StringRef secname;
45436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (error(Section.getName(secname)))
45536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      continue;
45627781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer    outs() << "RELOCATION RECORDS FOR [" << secname << "]:\n";
45736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    for (const RelocationRef &Reloc : Section.relocations()) {
4580685e94895f26f96aa1032696e3150dd00aad1f3Owen Anderson      bool hidden;
45927781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer      uint64_t address;
46027781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer      SmallString<32> relocname;
46127781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer      SmallString<32> valuestr;
46236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (error(Reloc.getHidden(hidden)))
46336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        continue;
46436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (hidden)
46536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        continue;
46636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (error(Reloc.getTypeName(relocname)))
46736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        continue;
46836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (error(Reloc.getOffset(address)))
46936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        continue;
47036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (error(Reloc.getValueString(valuestr)))
47136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        continue;
47236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      outs() << format(Fmt.data(), address) << " " << relocname << " "
47336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines             << valuestr << "\n";
47427781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer    }
47527781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer    outs() << "\n";
47627781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer  }
47727781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer}
47827781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer
479ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesvoid llvm::PrintSectionHeaders(const ObjectFile *Obj) {
480023bb15beaac3744ce3a5d1f750d6e32829c7130Nick Lewycky  outs() << "Sections:\n"
481023bb15beaac3744ce3a5d1f750d6e32829c7130Nick Lewycky            "Idx Name          Size      Address          Type\n";
482023bb15beaac3744ce3a5d1f750d6e32829c7130Nick Lewycky  unsigned i = 0;
48336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  for (const SectionRef &Section : Obj->sections()) {
484023bb15beaac3744ce3a5d1f750d6e32829c7130Nick Lewycky    StringRef Name;
48536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (error(Section.getName(Name)))
48636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return;
48737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint64_t Address = Section.getAddress();
48837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint64_t Size = Section.getSize();
48937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    bool Text = Section.isText();
49037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    bool Data = Section.isData();
49137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    bool BSS = Section.isBSS();
492023bb15beaac3744ce3a5d1f750d6e32829c7130Nick Lewycky    std::string Type = (std::string(Text ? "TEXT " : "") +
49314a5f468d6b18b7637821e13e56fe56dd79d7cafMichael J. Spencer                        (Data ? "DATA " : "") + (BSS ? "BSS" : ""));
49436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    outs() << format("%3d %-13s %08" PRIx64 " %016" PRIx64 " %s\n", i,
49536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                     Name.str().c_str(), Size, Address, Type.c_str());
496023bb15beaac3744ce3a5d1f750d6e32829c7130Nick Lewycky    ++i;
497023bb15beaac3744ce3a5d1f750d6e32829c7130Nick Lewycky  }
498023bb15beaac3744ce3a5d1f750d6e32829c7130Nick Lewycky}
499023bb15beaac3744ce3a5d1f750d6e32829c7130Nick Lewycky
500ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesvoid llvm::PrintSectionContents(const ObjectFile *Obj) {
501c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  std::error_code EC;
50236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  for (const SectionRef &Section : Obj->sections()) {
5031e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer    StringRef Name;
5041e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer    StringRef Contents;
50536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (error(Section.getName(Name)))
50636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      continue;
50737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint64_t BaseAddr = Section.getAddress();
50837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint64_t Size = Section.getSize();
50937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (!Size)
51036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      continue;
5111e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer
5121e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer    outs() << "Contents of section " << Name << ":\n";
51337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (Section.isBSS()) {
5140eaa6f675cafb2bb1b6a6210797c1d7b3da3ff9fAlexey Samsonov      outs() << format("<skipping contents of bss section at [%04" PRIx64
51537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                       ", %04" PRIx64 ")>\n",
51637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                       BaseAddr, BaseAddr + Size);
5170eaa6f675cafb2bb1b6a6210797c1d7b3da3ff9fAlexey Samsonov      continue;
5180eaa6f675cafb2bb1b6a6210797c1d7b3da3ff9fAlexey Samsonov    }
5191e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer
52037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (error(Section.getContents(Contents)))
52137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      continue;
52237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
5231e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer    // Dump out the content as hex and printable ascii characters.
5241e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer    for (std::size_t addr = 0, end = Contents.size(); addr < end; addr += 16) {
52551cf8661637c114e4b4f178bd2677a6bb246be0dBenjamin Kramer      outs() << format(" %04" PRIx64 " ", BaseAddr + addr);
5261e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer      // Dump line of hex.
5271e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer      for (std::size_t i = 0; i < 16; ++i) {
5281e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer        if (i != 0 && i % 4 == 0)
5291e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer          outs() << ' ';
5301e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer        if (addr + i < end)
5311e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer          outs() << hexdigit((Contents[addr + i] >> 4) & 0xF, true)
5321e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer                 << hexdigit(Contents[addr + i] & 0xF, true);
5331e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer        else
5341e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer          outs() << "  ";
5351e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer      }
5361e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer      // Print ascii.
5371e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer      outs() << "  ";
5381e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer      for (std::size_t i = 0; i < 16 && addr + i < end; ++i) {
53987d0b9ed1462705dd9bf1cb7f67d0bf03af776c8Guy Benyei        if (std::isprint(static_cast<unsigned char>(Contents[addr + i]) & 0xFF))
5401e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer          outs() << Contents[addr + i];
5411e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer        else
5421e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer          outs() << ".";
5431e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer      }
5441e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer      outs() << "\n";
5451e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer    }
5461e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer  }
5471e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer}
5481e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer
54922ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencerstatic void PrintCOFFSymbolTable(const COFFObjectFile *coff) {
55037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  for (unsigned SI = 0, SE = coff->getNumberOfSymbols(); SI != SE; ++SI) {
55137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    ErrorOr<COFFSymbolRef> Symbol = coff->getSymbol(SI);
552dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    StringRef Name;
55337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (error(Symbol.getError()))
554dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return;
555dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
55637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (error(coff->getSymbolName(*Symbol, Name)))
557dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return;
558dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
559dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    outs() << "[" << format("%2d", SI) << "]"
56037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines           << "(sec " << format("%2d", int(Symbol->getSectionNumber())) << ")"
561dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines           << "(fl 0x00)" // Flag bits, which COFF doesn't have.
56237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines           << "(ty " << format("%3x", unsigned(Symbol->getType())) << ")"
56337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines           << "(scl " << format("%3x", unsigned(Symbol->getStorageClass())) << ") "
56437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines           << "(nx " << unsigned(Symbol->getNumberOfAuxSymbols()) << ") "
56537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines           << "0x" << format("%08x", unsigned(Symbol->getValue())) << " "
566dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines           << Name << "\n";
567dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
56837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    for (unsigned AI = 0, AE = Symbol->getNumberOfAuxSymbols(); AI < AE; ++AI, ++SI) {
569dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (Symbol->isSectionDefinition()) {
57022ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencer        const coff_aux_section_definition *asd;
571dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        if (error(coff->getAuxSymbol<coff_aux_section_definition>(SI + 1, asd)))
57222ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencer          return;
573dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
57437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        int32_t AuxNumber = asd->getNumber(Symbol->isBigObj());
57537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
57622ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencer        outs() << "AUX "
57722ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencer               << format("scnlen 0x%x nreloc %d nlnno %d checksum 0x%x "
57822ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencer                         , unsigned(asd->Length)
57922ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencer                         , unsigned(asd->NumberOfRelocations)
58022ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencer                         , unsigned(asd->NumberOfLinenumbers)
58122ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencer                         , unsigned(asd->CheckSum))
58222ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencer               << format("assoc %d comdat %d\n"
58337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                         , unsigned(AuxNumber)
58422ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencer                         , unsigned(asd->Selection));
585dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      } else if (Symbol->isFileRecord()) {
58637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        const char *FileName;
58737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        if (error(coff->getAuxSymbol<char>(SI + 1, FileName)))
588dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          return;
589dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
59037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        StringRef Name(FileName, Symbol->getNumberOfAuxSymbols() *
59137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                     coff->getSymbolTableEntrySize());
592dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        outs() << "AUX " << Name.rtrim(StringRef("\0", 1))  << '\n';
593dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
59437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        SI = SI + Symbol->getNumberOfAuxSymbols();
595dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        break;
596dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      } else {
59722ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencer        outs() << "AUX Unknown\n";
598dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      }
59922ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencer    }
60022ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencer  }
60122ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencer}
60222ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencer
603ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesvoid llvm::PrintSymbolTable(const ObjectFile *o) {
60422ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencer  outs() << "SYMBOL TABLE:\n";
60522ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencer
60636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (const COFFObjectFile *coff = dyn_cast<const COFFObjectFile>(o)) {
60722ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencer    PrintCOFFSymbolTable(coff);
60836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return;
60936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
61036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  for (const SymbolRef &Symbol : o->symbols()) {
61136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    StringRef Name;
61236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    uint64_t Address;
61336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    SymbolRef::Type Type;
61436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    uint64_t Size;
61536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    uint32_t Flags = Symbol.getFlags();
61636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    section_iterator Section = o->section_end();
61736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (error(Symbol.getName(Name)))
61836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      continue;
61936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (error(Symbol.getAddress(Address)))
62036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      continue;
62136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (error(Symbol.getType(Type)))
62236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      continue;
62336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (error(Symbol.getSize(Size)))
62436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      continue;
62536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (error(Symbol.getSection(Section)))
62636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      continue;
62736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
62836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    bool Global = Flags & SymbolRef::SF_Global;
62936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    bool Weak = Flags & SymbolRef::SF_Weak;
63036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    bool Absolute = Flags & SymbolRef::SF_Absolute;
631ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    bool Common = Flags & SymbolRef::SF_Common;
632ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
633ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (Common) {
634ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      uint32_t Alignment;
635ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      if (error(Symbol.getAlignment(Alignment)))
636ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        Alignment = 0;
637ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      Address = Size;
638ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      Size = Alignment;
639ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    }
64036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (Address == UnknownAddressOrSize)
64136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Address = 0;
64236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (Size == UnknownAddressOrSize)
64336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Size = 0;
64436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    char GlobLoc = ' ';
64536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (Type != SymbolRef::ST_Unknown)
64636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      GlobLoc = Global ? 'g' : 'l';
64736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    char Debug = (Type == SymbolRef::ST_Debug || Type == SymbolRef::ST_File)
64836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                 ? 'd' : ' ';
64936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    char FileFunc = ' ';
65036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (Type == SymbolRef::ST_File)
65136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      FileFunc = 'f';
65236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    else if (Type == SymbolRef::ST_Function)
65336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      FileFunc = 'F';
65436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
65536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    const char *Fmt = o->getBytesInAddress() > 4 ? "%016" PRIx64 :
65636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                                   "%08" PRIx64;
65736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
65836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    outs() << format(Fmt, Address) << " "
65936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines           << GlobLoc // Local -> 'l', Global -> 'g', Neither -> ' '
66036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines           << (Weak ? 'w' : ' ') // Weak?
66136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines           << ' ' // Constructor. Not supported yet.
66236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines           << ' ' // Warning. Not supported yet.
66336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines           << ' ' // Indirect reference to another symbol.
66436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines           << Debug // Debugging (d) or dynamic (D) symbol.
66536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines           << FileFunc // Name of function (F), file (f) or object (O).
66636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines           << ' ';
66736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (Absolute) {
66836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      outs() << "*ABS*";
669ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    } else if (Common) {
670ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      outs() << "*COM*";
67136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    } else if (Section == o->section_end()) {
67236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      outs() << "*UND*";
67336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    } else {
67436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (const MachOObjectFile *MachO =
67536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          dyn_cast<const MachOObjectFile>(o)) {
67636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        DataRefImpl DR = Section->getRawDataRefImpl();
67736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        StringRef SegmentName = MachO->getSectionFinalSegmentName(DR);
67836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        outs() << SegmentName << ",";
67922ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencer      }
68036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      StringRef SectionName;
68136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (error(Section->getName(SectionName)))
68236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        SectionName = "";
68336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      outs() << SectionName;
68422ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencer    }
68536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    outs() << '\t'
68636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines           << format("%08" PRIx64 " ", Size)
68736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines           << Name
68836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines           << '\n';
68922ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencer  }
69022ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencer}
69122ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencer
692eef7b6219ebe5d0ded0be4adb3003055fa8a63c4Michael J. Spencerstatic void PrintUnwindInfo(const ObjectFile *o) {
693eef7b6219ebe5d0ded0be4adb3003055fa8a63c4Michael J. Spencer  outs() << "Unwind info:\n\n";
694eef7b6219ebe5d0ded0be4adb3003055fa8a63c4Michael J. Spencer
695eef7b6219ebe5d0ded0be4adb3003055fa8a63c4Michael J. Spencer  if (const COFFObjectFile *coff = dyn_cast<COFFObjectFile>(o)) {
696eef7b6219ebe5d0ded0be4adb3003055fa8a63c4Michael J. Spencer    printCOFFUnwindInfo(coff);
69737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  } else if (const MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o))
69837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    printMachOUnwindInfo(MachO);
69937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else {
700eef7b6219ebe5d0ded0be4adb3003055fa8a63c4Michael J. Spencer    // TODO: Extract DWARF dump tool to objdump.
701eef7b6219ebe5d0ded0be4adb3003055fa8a63c4Michael J. Spencer    errs() << "This operation is only currently supported "
70237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines              "for COFF and MachO object files.\n";
70337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return;
70437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
70537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
70637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
707ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesvoid llvm::printExportsTrie(const ObjectFile *o) {
70837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "Exports trie:\n";
70937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (const MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o))
71037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    printMachOExportsTrie(MachO);
71137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else {
71237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    errs() << "This operation is only currently supported "
71337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines              "for Mach-O executable files.\n";
71437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return;
71537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
71637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
71737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
718ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesvoid llvm::printRebaseTable(const ObjectFile *o) {
71937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "Rebase table:\n";
72037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (const MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o))
72137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    printMachORebaseTable(MachO);
72237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else {
72337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    errs() << "This operation is only currently supported "
72437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines              "for Mach-O executable files.\n";
72537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return;
72637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
72737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
72837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
729ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesvoid llvm::printBindTable(const ObjectFile *o) {
73037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "Bind table:\n";
73137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (const MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o))
73237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    printMachOBindTable(MachO);
73337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else {
73437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    errs() << "This operation is only currently supported "
73537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines              "for Mach-O executable files.\n";
73637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return;
73737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
73837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
73937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
740ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesvoid llvm::printLazyBindTable(const ObjectFile *o) {
74137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "Lazy bind table:\n";
74237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (const MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o))
74337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    printMachOLazyBindTable(MachO);
74437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else {
74537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    errs() << "This operation is only currently supported "
74637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines              "for Mach-O executable files.\n";
74737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return;
74837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
74937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
75037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
751ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesvoid llvm::printWeakBindTable(const ObjectFile *o) {
75237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  outs() << "Weak bind table:\n";
75337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (const MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o))
75437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    printMachOWeakBindTable(MachO);
75537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else {
75637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    errs() << "This operation is only currently supported "
75737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines              "for Mach-O executable files.\n";
758eef7b6219ebe5d0ded0be4adb3003055fa8a63c4Michael J. Spencer    return;
759eef7b6219ebe5d0ded0be4adb3003055fa8a63c4Michael J. Spencer  }
760eef7b6219ebe5d0ded0be4adb3003055fa8a63c4Michael J. Spencer}
761eef7b6219ebe5d0ded0be4adb3003055fa8a63c4Michael J. Spencer
762a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyamastatic void printPrivateFileHeader(const ObjectFile *o) {
763a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama  if (o->isELF()) {
764a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama    printELFFileHeader(o);
765a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama  } else if (o->isCOFF()) {
766a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama    printCOFFFileHeader(o);
76737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  } else if (o->isMachO()) {
76837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    printMachOFileHeader(o);
769a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama  }
770a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama}
771a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama
77227781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencerstatic void DumpObject(const ObjectFile *o) {
7731e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer  outs() << '\n';
7741e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer  outs() << o->getFileName()
7751e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer         << ":\tfile format " << o->getFileFormatName() << "\n\n";
7761e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer
77727781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer  if (Disassemble)
778942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer    DisassembleObject(o, Relocations);
779942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer  if (Relocations && !Disassemble)
78027781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer    PrintRelocations(o);
781023bb15beaac3744ce3a5d1f750d6e32829c7130Nick Lewycky  if (SectionHeaders)
782023bb15beaac3744ce3a5d1f750d6e32829c7130Nick Lewycky    PrintSectionHeaders(o);
7831e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer  if (SectionContents)
7841e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer    PrintSectionContents(o);
78522ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencer  if (SymbolTable)
78622ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencer    PrintSymbolTable(o);
787eef7b6219ebe5d0ded0be4adb3003055fa8a63c4Michael J. Spencer  if (UnwindInfo)
788eef7b6219ebe5d0ded0be4adb3003055fa8a63c4Michael J. Spencer    PrintUnwindInfo(o);
789a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama  if (PrivateHeaders)
790a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama    printPrivateFileHeader(o);
79137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (ExportsTrie)
79237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    printExportsTrie(o);
79337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Rebase)
79437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    printRebaseTable(o);
79537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Bind)
79637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    printBindTable(o);
79737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (LazyBind)
79837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    printLazyBindTable(o);
79937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (WeakBind)
80037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    printWeakBindTable(o);
80127781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer}
80227781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer
80327781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer/// @brief Dump each object file in \a a;
80427781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencerstatic void DumpArchive(const Archive *a) {
80536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  for (Archive::child_iterator i = a->child_begin(), e = a->child_end(); i != e;
80636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines       ++i) {
807c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    ErrorOr<std::unique_ptr<Binary>> ChildOrErr = i->getAsBinary();
808c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    if (std::error_code EC = ChildOrErr.getError()) {
809f81285c0c507908b429a2c4cbd0683d624d375f9Michael J. Spencer      // Ignore non-object files.
81036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (EC != object_error::invalid_file_type)
81136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        errs() << ToolName << ": '" << a->getFileName() << "': " << EC.message()
812f81285c0c507908b429a2c4cbd0683d624d375f9Michael J. Spencer               << ".\n";
81327781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer      continue;
81427781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer    }
815c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    if (ObjectFile *o = dyn_cast<ObjectFile>(&*ChildOrErr.get()))
81627781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer      DumpObject(o);
81727781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer    else
81827781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer      errs() << ToolName << ": '" << a->getFileName() << "': "
81927781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer              << "Unrecognized file type.\n";
82027781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer  }
82127781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer}
82227781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer
82327781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer/// @brief Open file and figure out how to dump it.
82427781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencerstatic void DumpInput(StringRef file) {
82527781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer  // If file isn't stdin, check that it exists.
82627781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer  if (file != "-" && !sys::fs::exists(file)) {
82727781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer    errs() << ToolName << ": '" << file << "': " << "No such file\n";
82827781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer    return;
82927781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer  }
83027781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer
831ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // If we are using the Mach-O specific object file parser, then let it parse
832ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // the file and process the command line options.  So the -arch flags can
833ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // be used to select specific slices, etc.
834ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (MachOOpt) {
835ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    ParseInputMachO(file);
83627781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer    return;
83727781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer  }
83827781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer
83927781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer  // Attempt to open the binary.
84037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  ErrorOr<OwningBinary<Binary>> BinaryOrErr = createBinary(file);
841c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  if (std::error_code EC = BinaryOrErr.getError()) {
84236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    errs() << ToolName << ": '" << file << "': " << EC.message() << ".\n";
84327781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer    return;
84427781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer  }
84537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Binary &Binary = *BinaryOrErr.get().getBinary();
84627781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer
84737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Archive *a = dyn_cast<Archive>(&Binary))
84827781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer    DumpArchive(a);
84937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else if (ObjectFile *o = dyn_cast<ObjectFile>(&Binary))
85027781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer    DumpObject(o);
8513f5d1a2396915ebff20ce4f5d668ee5c839d1d91Jim Grosbach  else
85227781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer    errs() << ToolName << ": '" << file << "': " << "Unrecognized file type.\n";
85327781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer}
85427781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer
85592e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencerint main(int argc, char **argv) {
85692e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  // Print a stack trace if we signal out.
85792e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  sys::PrintStackTraceOnErrorSignal();
85892e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  PrettyStackTraceProgram X(argc, argv);
85992e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.
86092e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer
86192e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  // Initialize targets and assembly printers/parsers.
86292e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  llvm::InitializeAllTargetInfos();
863e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng  llvm::InitializeAllTargetMCs();
86492e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  llvm::InitializeAllAsmParsers();
86592e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  llvm::InitializeAllDisassemblers();
86692e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer
867ff204963cbcd7c68d59f3bba5bfa2797ea0cebaePete Cooper  // Register the target printer for --version.
868ff204963cbcd7c68d59f3bba5bfa2797ea0cebaePete Cooper  cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion);
869ff204963cbcd7c68d59f3bba5bfa2797ea0cebaePete Cooper
87092e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  cl::ParseCommandLineOptions(argc, argv, "llvm object file dumper\n");
87192e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  TripleName = Triple::normalize(TripleName);
87292e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer
87392e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  ToolName = argv[0];
87492e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer
87592e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  // Defaults to a.out if no filenames specified.
87692e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  if (InputFilenames.size() == 0)
87792e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer    InputFilenames.push_back("a.out");
87892e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer
87922ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencer  if (!Disassemble
88022ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencer      && !Relocations
88122ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencer      && !SectionHeaders
88222ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencer      && !SectionContents
883eef7b6219ebe5d0ded0be4adb3003055fa8a63c4Michael J. Spencer      && !SymbolTable
884b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer      && !UnwindInfo
88537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      && !PrivateHeaders
88637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      && !ExportsTrie
88737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      && !Rebase
88837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      && !Bind
88937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      && !LazyBind
890ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      && !WeakBind
891ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      && !(UniversalHeaders && MachOOpt)
892ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      && !(ArchiveHeaders && MachOOpt)
893ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      && !(IndirectSymbols && MachOOpt)
894ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      && !(DataInCode && MachOOpt)
895ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      && !(LinkOptHints && MachOOpt)
8964c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      && !(InfoPlist && MachOOpt)
8974c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      && !(DylibsUsed && MachOOpt)
8984c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      && !(DylibId && MachOOpt)
8992c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar      && !(ObjcMetaData && MachOOpt)
900ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      && !(DumpSections.size() != 0 && MachOOpt)) {
90192e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer    cl::PrintHelpMessage();
90292e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer    return 2;
90392e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer  }
90492e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer
90527781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer  std::for_each(InputFilenames.begin(), InputFilenames.end(),
90627781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer                DumpInput);
90792e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer
908ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  return ReturnValue;
90992e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer}
910