10b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer//===-- MachODump.cpp - Object file dumping utility for llvm --------------===//
20b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer//
30b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer//                     The LLVM Compiler Infrastructure
40b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer//
50b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer// This file is distributed under the University of Illinois Open Source
60b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer// License. See LICENSE.TXT for details.
70b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer//
80b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer//===----------------------------------------------------------------------===//
90b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer//
100b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer// This file implements the MachO-specific dumper for llvm-objdump.
110b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer//
120b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer//===----------------------------------------------------------------------===//
130b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
140b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include "llvm-objdump.h"
150b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include "llvm/ADT/STLExtras.h"
16ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha#include "llvm/ADT/StringExtras.h"
17f010c464a11444733ec67e31aace8bcebeaf2588Chandler Carruth#include "llvm/ADT/Triple.h"
188c93097c4c5e6dddc8c239295a1b42217b082ad3Benjamin Kramer#include "llvm/DebugInfo/DIContext.h"
190b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include "llvm/MC/MCAsmInfo.h"
20dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "llvm/MC/MCContext.h"
210b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include "llvm/MC/MCDisassembler.h"
220b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include "llvm/MC/MCInst.h"
230b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include "llvm/MC/MCInstPrinter.h"
240b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include "llvm/MC/MCInstrAnalysis.h"
250b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include "llvm/MC/MCInstrDesc.h"
260b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include "llvm/MC/MCInstrInfo.h"
27c6449b636f4984be88f128d0375c056ad05e7e8fJim Grosbach#include "llvm/MC/MCRegisterInfo.h"
280b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include "llvm/MC/MCSubtargetInfo.h"
29f010c464a11444733ec67e31aace8bcebeaf2588Chandler Carruth#include "llvm/Object/MachO.h"
30da2a2372c6ae715befae7f086afe769dd80814f3Rafael Espindola#include "llvm/Support/Casting.h"
310b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include "llvm/Support/CommandLine.h"
320b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include "llvm/Support/Debug.h"
330b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include "llvm/Support/Format.h"
340b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include "llvm/Support/GraphWriter.h"
35f010c464a11444733ec67e31aace8bcebeaf2588Chandler Carruth#include "llvm/Support/MachO.h"
360b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include "llvm/Support/MemoryBuffer.h"
370b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include "llvm/Support/TargetRegistry.h"
380b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include "llvm/Support/TargetSelect.h"
390b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include "llvm/Support/raw_ostream.h"
400b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include <algorithm>
410b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include <cstring>
42cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines#include <system_error>
430b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramerusing namespace llvm;
440b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramerusing namespace object;
450b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
460b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramerstatic cl::opt<bool>
478c93097c4c5e6dddc8c239295a1b42217b082ad3Benjamin Kramer  UseDbg("g", cl::desc("Print line information from debug info if available"));
488c93097c4c5e6dddc8c239295a1b42217b082ad3Benjamin Kramer
498c93097c4c5e6dddc8c239295a1b42217b082ad3Benjamin Kramerstatic cl::opt<std::string>
508c93097c4c5e6dddc8c239295a1b42217b082ad3Benjamin Kramer  DSYMFile("dsym", cl::desc("Use .dSYM file for debug info"));
518c93097c4c5e6dddc8c239295a1b42217b082ad3Benjamin Kramer
52fd7aa38e304a09fa0ef51b85b773b649b7e58c5eRafael Espindolastatic const Target *GetTarget(const MachOObjectFile *MachOObj) {
530b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  // Figure out the target triple.
54a99350511cceb8a723800957bae500078f054062Cameron Zwarich  if (TripleName.empty()) {
55a99350511cceb8a723800957bae500078f054062Cameron Zwarich    llvm::Triple TT("unknown-unknown-unknown");
56317d3f48fd53be5238dfba5e9fbac51a2366de0eRafael Espindola    TT.setArch(Triple::ArchType(MachOObj->getArch()));
57a99350511cceb8a723800957bae500078f054062Cameron Zwarich    TripleName = TT.str();
580b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  }
590b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
600b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  // Get the target specific parser.
610b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  std::string Error;
620b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  const Target *TheTarget = TargetRegistry::lookupTarget(TripleName, Error);
630b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  if (TheTarget)
640b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    return TheTarget;
650b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
660b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  errs() << "llvm-objdump: error: unable to get target for '" << TripleName
670b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer         << "', see --version and --triple.\n";
68dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return nullptr;
690b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer}
700b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
71481837a743be2bd4723d96f304abba93140dc206Owen Andersonstruct SymbolSorter {
72481837a743be2bd4723d96f304abba93140dc206Owen Anderson  bool operator()(const SymbolRef &A, const SymbolRef &B) {
73481837a743be2bd4723d96f304abba93140dc206Owen Anderson    SymbolRef::Type AType, BType;
74481837a743be2bd4723d96f304abba93140dc206Owen Anderson    A.getType(AType);
75481837a743be2bd4723d96f304abba93140dc206Owen Anderson    B.getType(BType);
76481837a743be2bd4723d96f304abba93140dc206Owen Anderson
77481837a743be2bd4723d96f304abba93140dc206Owen Anderson    uint64_t AAddr, BAddr;
78481837a743be2bd4723d96f304abba93140dc206Owen Anderson    if (AType != SymbolRef::ST_Function)
79481837a743be2bd4723d96f304abba93140dc206Owen Anderson      AAddr = 0;
80481837a743be2bd4723d96f304abba93140dc206Owen Anderson    else
81481837a743be2bd4723d96f304abba93140dc206Owen Anderson      A.getAddress(AAddr);
82481837a743be2bd4723d96f304abba93140dc206Owen Anderson    if (BType != SymbolRef::ST_Function)
83481837a743be2bd4723d96f304abba93140dc206Owen Anderson      BAddr = 0;
84481837a743be2bd4723d96f304abba93140dc206Owen Anderson    else
85481837a743be2bd4723d96f304abba93140dc206Owen Anderson      B.getAddress(BAddr);
86481837a743be2bd4723d96f304abba93140dc206Owen Anderson    return AAddr < BAddr;
87481837a743be2bd4723d96f304abba93140dc206Owen Anderson  }
880b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer};
890b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
9054154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby// Types for the storted data in code table that is built before disassembly
9154154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby// and the predicate function to sort them.
9254154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderbytypedef std::pair<uint64_t, DiceRef> DiceTableEntry;
9354154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderbytypedef std::vector<DiceTableEntry> DiceTable;
9454154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderbytypedef DiceTable::iterator dice_table_iterator;
9554154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby
9654154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderbystatic bool
9754154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin EnderbycompareDiceTableEntries(const DiceTableEntry i,
9854154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby                        const DiceTableEntry j) {
9954154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby  return i.first == j.first;
10054154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby}
10154154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby
10254154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderbystatic void DumpDataInCode(const char *bytes, uint64_t Size,
10354154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby                           unsigned short Kind) {
10454154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby  uint64_t Value;
10554154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby
10654154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby  switch (Kind) {
1075510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  case MachO::DICE_KIND_DATA:
10854154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby    switch (Size) {
10954154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby    case 4:
11054154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby      Value = bytes[3] << 24 |
11154154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby              bytes[2] << 16 |
11254154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby              bytes[1] << 8 |
11354154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby              bytes[0];
11454154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby      outs() << "\t.long " << Value;
11554154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby      break;
11654154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby    case 2:
11754154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby      Value = bytes[1] << 8 |
11854154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby              bytes[0];
11954154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby      outs() << "\t.short " << Value;
12054154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby      break;
12154154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby    case 1:
12254154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby      Value = bytes[0];
12354154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby      outs() << "\t.byte " << Value;
12454154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby      break;
12554154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby    }
12654154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby    outs() << "\t@ KIND_DATA\n";
12754154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby    break;
1285510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  case MachO::DICE_KIND_JUMP_TABLE8:
12954154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby    Value = bytes[0];
13054154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby    outs() << "\t.byte " << Value << "\t@ KIND_JUMP_TABLE8";
13154154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby    break;
1325510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  case MachO::DICE_KIND_JUMP_TABLE16:
13354154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby    Value = bytes[1] << 8 |
13454154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby            bytes[0];
13554154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby    outs() << "\t.short " << Value << "\t@ KIND_JUMP_TABLE16";
13654154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby    break;
1375510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  case MachO::DICE_KIND_JUMP_TABLE32:
13854154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby    Value = bytes[3] << 24 |
13954154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby            bytes[2] << 16 |
14054154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby            bytes[1] << 8 |
14154154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby            bytes[0];
14254154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby    outs() << "\t.long " << Value << "\t@ KIND_JUMP_TABLE32";
14354154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby    break;
14454154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby  default:
14554154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby    outs() << "\t@ data in code kind = " << Kind << "\n";
14654154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby    break;
14754154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby  }
14854154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby}
14954154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby
15036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic void getSectionsAndSymbols(const MachO::mach_header Header,
15136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                  MachOObjectFile *MachOObj,
15236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                  std::vector<SectionRef> &Sections,
15336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                  std::vector<SymbolRef> &Symbols,
15436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                  SmallVectorImpl<uint64_t> &FoundFns,
15536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                  uint64_t &BaseSegmentAddress) {
15636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  for (const SymbolRef &Symbol : MachOObj->symbols())
15736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Symbols.push_back(Symbol);
15836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
15936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  for (const SectionRef &Section : MachOObj->sections()) {
160481837a743be2bd4723d96f304abba93140dc206Owen Anderson    StringRef SectName;
16136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Section.getName(SectName);
16236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Sections.push_back(Section);
163481837a743be2bd4723d96f304abba93140dc206Owen Anderson  }
1648c93097c4c5e6dddc8c239295a1b42217b082ad3Benjamin Kramer
165fd7aa38e304a09fa0ef51b85b773b649b7e58c5eRafael Espindola  MachOObjectFile::LoadCommandInfo Command =
16636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      MachOObj->getFirstLoadCommandInfo();
16754154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby  bool BaseSegmentAddressSet = false;
168db5f9270207292b62ea847560c5dd4e9873b57f5Rafael Espindola  for (unsigned i = 0; ; ++i) {
1695510728d28bb1ee04abc32da3d21b7df12948053Charles Davis    if (Command.C.cmd == MachO::LC_FUNCTION_STARTS) {
1708c93097c4c5e6dddc8c239295a1b42217b082ad3Benjamin Kramer      // We found a function starts segment, parse the addresses for later
1718c93097c4c5e6dddc8c239295a1b42217b082ad3Benjamin Kramer      // consumption.
1725510728d28bb1ee04abc32da3d21b7df12948053Charles Davis      MachO::linkedit_data_command LLC =
173fd7aa38e304a09fa0ef51b85b773b649b7e58c5eRafael Espindola        MachOObj->getLinkeditDataLoadCommand(Command);
1748c93097c4c5e6dddc8c239295a1b42217b082ad3Benjamin Kramer
1755510728d28bb1ee04abc32da3d21b7df12948053Charles Davis      MachOObj->ReadULEB128s(LLC.dataoff, FoundFns);
176afbaf48fc4a645a95737ea81e2e0fde47a6150baBenjamin Kramer    }
1775510728d28bb1ee04abc32da3d21b7df12948053Charles Davis    else if (Command.C.cmd == MachO::LC_SEGMENT) {
1785510728d28bb1ee04abc32da3d21b7df12948053Charles Davis      MachO::segment_command SLC =
17954154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby        MachOObj->getSegmentLoadCommand(Command);
1805510728d28bb1ee04abc32da3d21b7df12948053Charles Davis      StringRef SegName = SLC.segname;
18154154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby      if(!BaseSegmentAddressSet && SegName != "__PAGEZERO") {
18254154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby        BaseSegmentAddressSet = true;
1835510728d28bb1ee04abc32da3d21b7df12948053Charles Davis        BaseSegmentAddress = SLC.vmaddr;
18454154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby      }
18554154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby    }
186db5f9270207292b62ea847560c5dd4e9873b57f5Rafael Espindola
1875510728d28bb1ee04abc32da3d21b7df12948053Charles Davis    if (i == Header.ncmds - 1)
188db5f9270207292b62ea847560c5dd4e9873b57f5Rafael Espindola      break;
189db5f9270207292b62ea847560c5dd4e9873b57f5Rafael Espindola    else
190db5f9270207292b62ea847560c5dd4e9873b57f5Rafael Espindola      Command = MachOObj->getNextLoadCommandInfo(Command);
191afbaf48fc4a645a95737ea81e2e0fde47a6150baBenjamin Kramer  }
1928c93097c4c5e6dddc8c239295a1b42217b082ad3Benjamin Kramer}
1938c93097c4c5e6dddc8c239295a1b42217b082ad3Benjamin Kramer
194da2a2372c6ae715befae7f086afe769dd80814f3Rafael Espindolastatic void DisassembleInputMachO2(StringRef Filename,
195fd7aa38e304a09fa0ef51b85b773b649b7e58c5eRafael Espindola                                   MachOObjectFile *MachOOF);
196da2a2372c6ae715befae7f086afe769dd80814f3Rafael Espindola
1970b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramervoid llvm::DisassembleInputMachO(StringRef Filename) {
198cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  ErrorOr<std::unique_ptr<MemoryBuffer>> Buff =
199cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      MemoryBuffer::getFileOrSTDIN(Filename);
200cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (std::error_code EC = Buff.getError()) {
201cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    errs() << "llvm-objdump: " << Filename << ": " << EC.message() << "\n";
2020b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    return;
2030b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  }
2040b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
20536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  std::unique_ptr<MachOObjectFile> MachOOF(static_cast<MachOObjectFile *>(
206cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      ObjectFile::createMachOObjectFile(Buff.get()).get()));
2070b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
208fd7aa38e304a09fa0ef51b85b773b649b7e58c5eRafael Espindola  DisassembleInputMachO2(Filename, MachOOF.get());
209da2a2372c6ae715befae7f086afe769dd80814f3Rafael Espindola}
210da2a2372c6ae715befae7f086afe769dd80814f3Rafael Espindola
211da2a2372c6ae715befae7f086afe769dd80814f3Rafael Espindolastatic void DisassembleInputMachO2(StringRef Filename,
212fd7aa38e304a09fa0ef51b85b773b649b7e58c5eRafael Espindola                                   MachOObjectFile *MachOOF) {
213da2a2372c6ae715befae7f086afe769dd80814f3Rafael Espindola  const Target *TheTarget = GetTarget(MachOOF);
2140b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  if (!TheTarget) {
2150b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    // GetTarget prints out stuff.
2160b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    return;
2170b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  }
21836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  std::unique_ptr<const MCInstrInfo> InstrInfo(TheTarget->createMCInstrInfo());
21936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  std::unique_ptr<MCInstrAnalysis> InstrAnalysis(
22036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      TheTarget->createMCInstrAnalysis(InstrInfo.get()));
2210b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
2220b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  // Set up disassembler.
22336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  std::unique_ptr<const MCRegisterInfo> MRI(
22436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      TheTarget->createMCRegInfo(TripleName));
22536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  std::unique_ptr<const MCAsmInfo> AsmInfo(
2264a971705bc6030dc2e4338b3cd5cffa2e0f88b7bRafael Espindola      TheTarget->createMCAsmInfo(*MRI, TripleName));
22736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  std::unique_ptr<const MCSubtargetInfo> STI(
22836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      TheTarget->createMCSubtargetInfo(TripleName, "", ""));
229dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MCContext Ctx(AsmInfo.get(), MRI.get(), nullptr);
23036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  std::unique_ptr<const MCDisassembler> DisAsm(
231dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    TheTarget->createMCDisassembler(*STI, Ctx));
2320b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  int AsmPrinterVariant = AsmInfo->getAssemblerDialect();
23336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  std::unique_ptr<MCInstPrinter> IP(TheTarget->createMCInstPrinter(
23436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      AsmPrinterVariant, *AsmInfo, *InstrInfo, *MRI, *STI));
235a894c8e34453493a9d3fb2ffbbc21151c3965b63Benjamin Kramer
236a894c8e34453493a9d3fb2ffbbc21151c3965b63Benjamin Kramer  if (!InstrAnalysis || !AsmInfo || !STI || !DisAsm || !IP) {
2373773fb46ba530f69530d1c4bafb7885528a27391Michael J. Spencer    errs() << "error: couldn't initialize disassembler for target "
238a894c8e34453493a9d3fb2ffbbc21151c3965b63Benjamin Kramer           << TripleName << '\n';
2390b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    return;
2400b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  }
2410b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
242a894c8e34453493a9d3fb2ffbbc21151c3965b63Benjamin Kramer  outs() << '\n' << Filename << ":\n\n";
2430b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
2445510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  MachO::mach_header Header = MachOOF->getHeader();
2450b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
246ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  // FIXME: FoundFns isn't used anymore. Using symbols/LC_FUNCTION_STARTS to
247ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  // determine function locations will eventually go in MCObjectDisassembler.
248ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  // FIXME: Using the -cfg command line option, this code used to be able to
249ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  // annotate relocations with the referenced symbol's name, and if this was
250ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  // inside a __[cf]string section, the data it points to. This is now replaced
251ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  // by the upcoming MCSymbolizer, which needs the appropriate setup done above.
252481837a743be2bd4723d96f304abba93140dc206Owen Anderson  std::vector<SectionRef> Sections;
253481837a743be2bd4723d96f304abba93140dc206Owen Anderson  std::vector<SymbolRef> Symbols;
2540b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  SmallVector<uint64_t, 8> FoundFns;
25554154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby  uint64_t BaseSegmentAddress;
2560b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
25754154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby  getSectionsAndSymbols(Header, MachOOF, Sections, Symbols, FoundFns,
25854154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby                        BaseSegmentAddress);
2590b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
2600b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  // Sort the symbols by address, just in case they didn't come in that way.
261481837a743be2bd4723d96f304abba93140dc206Owen Anderson  std::sort(Symbols.begin(), Symbols.end(), SymbolSorter());
2620b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
26354154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby  // Build a data in code table that is sorted on by the address of each entry.
26454154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby  uint64_t BaseAddress = 0;
2655510728d28bb1ee04abc32da3d21b7df12948053Charles Davis  if (Header.filetype == MachO::MH_OBJECT)
26654154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby    Sections[0].getAddress(BaseAddress);
26754154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby  else
26854154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby    BaseAddress = BaseSegmentAddress;
26954154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby  DiceTable Dices;
27054154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby  for (dice_iterator DI = MachOOF->begin_dices(), DE = MachOOF->end_dices();
27136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines       DI != DE; ++DI) {
27254154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby    uint32_t Offset;
27354154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby    DI->getOffset(Offset);
27454154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby    Dices.push_back(std::make_pair(BaseAddress + Offset, *DI));
27554154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby  }
27654154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby  array_pod_sort(Dices.begin(), Dices.end());
27754154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby
2780b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#ifndef NDEBUG
2790b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  raw_ostream &DebugOut = DebugFlag ? dbgs() : nulls();
2800b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#else
2810b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  raw_ostream &DebugOut = nulls();
2820b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#endif
2830b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
28436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  std::unique_ptr<DIContext> diContext;
285da2a2372c6ae715befae7f086afe769dd80814f3Rafael Espindola  ObjectFile *DbgObj = MachOOF;
2868c93097c4c5e6dddc8c239295a1b42217b082ad3Benjamin Kramer  // Try to find debug info and set up the DIContext for it.
2878c93097c4c5e6dddc8c239295a1b42217b082ad3Benjamin Kramer  if (UseDbg) {
2888c93097c4c5e6dddc8c239295a1b42217b082ad3Benjamin Kramer    // A separate DSym file path was specified, parse it as a macho file,
2898c93097c4c5e6dddc8c239295a1b42217b082ad3Benjamin Kramer    // get the sections and supply it to the section name parsing machinery.
2908c93097c4c5e6dddc8c239295a1b42217b082ad3Benjamin Kramer    if (!DSYMFile.empty()) {
291cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      ErrorOr<std::unique_ptr<MemoryBuffer>> Buf =
292cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines          MemoryBuffer::getFileOrSTDIN(DSYMFile);
293cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      if (std::error_code EC = Buf.getError()) {
294cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        errs() << "llvm-objdump: " << Filename << ": " << EC.message() << '\n';
2958c93097c4c5e6dddc8c239295a1b42217b082ad3Benjamin Kramer        return;
2968c93097c4c5e6dddc8c239295a1b42217b082ad3Benjamin Kramer      }
297cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      DbgObj = ObjectFile::createMachOObjectFile(Buf.get()).get();
2988c93097c4c5e6dddc8c239295a1b42217b082ad3Benjamin Kramer    }
2998c93097c4c5e6dddc8c239295a1b42217b082ad3Benjamin Kramer
300d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher    // Setup the DIContext
301d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher    diContext.reset(DIContext::getDWARFContext(DbgObj));
3028c93097c4c5e6dddc8c239295a1b42217b082ad3Benjamin Kramer  }
3038c93097c4c5e6dddc8c239295a1b42217b082ad3Benjamin Kramer
3040b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  for (unsigned SectIdx = 0; SectIdx != Sections.size(); SectIdx++) {
305ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha
306ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha    bool SectIsText = false;
307ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha    Sections[SectIdx].isText(SectIsText);
308ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha    if (SectIsText == false)
309ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha      continue;
310ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha
311481837a743be2bd4723d96f304abba93140dc206Owen Anderson    StringRef SectName;
312481837a743be2bd4723d96f304abba93140dc206Owen Anderson    if (Sections[SectIdx].getName(SectName) ||
313cef81b37c77978cd4dddb4a5ad13564793ded155Rafael Espindola        SectName != "__text")
314a894c8e34453493a9d3fb2ffbbc21151c3965b63Benjamin Kramer      continue; // Skip non-text sections
3150b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
316cef81b37c77978cd4dddb4a5ad13564793ded155Rafael Espindola    DataRefImpl DR = Sections[SectIdx].getRawDataRefImpl();
317ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha
318f16c2bb320f4d5b33dfaf8df8865f547e6d66005Rafael Espindola    StringRef SegmentName = MachOOF->getSectionFinalSegmentName(DR);
319f16c2bb320f4d5b33dfaf8df8865f547e6d66005Rafael Espindola    if (SegmentName != "__TEXT")
320cef81b37c77978cd4dddb4a5ad13564793ded155Rafael Espindola      continue;
321cef81b37c77978cd4dddb4a5ad13564793ded155Rafael Espindola
322481837a743be2bd4723d96f304abba93140dc206Owen Anderson    StringRef Bytes;
323481837a743be2bd4723d96f304abba93140dc206Owen Anderson    Sections[SectIdx].getContents(Bytes);
3240b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    StringRefMemoryObject memoryObject(Bytes);
3250b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    bool symbolTableWorked = false;
3260b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
327a894c8e34453493a9d3fb2ffbbc21151c3965b63Benjamin Kramer    // Parse relocations.
32836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    std::vector<std::pair<uint64_t, SymbolRef>> Relocs;
32936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    for (const RelocationRef &Reloc : Sections[SectIdx].relocations()) {
330481837a743be2bd4723d96f304abba93140dc206Owen Anderson      uint64_t RelocOffset, SectionAddress;
33136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Reloc.getOffset(RelocOffset);
332481837a743be2bd4723d96f304abba93140dc206Owen Anderson      Sections[SectIdx].getAddress(SectionAddress);
333481837a743be2bd4723d96f304abba93140dc206Owen Anderson      RelocOffset -= SectionAddress;
334481837a743be2bd4723d96f304abba93140dc206Owen Anderson
33536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      symbol_iterator RelocSym = Reloc.getSymbol();
336481837a743be2bd4723d96f304abba93140dc206Owen Anderson
3376c1202c459ffa6d693ad92fa84e43902bc780bcaRafael Espindola      Relocs.push_back(std::make_pair(RelocOffset, *RelocSym));
3380b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    }
3390b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    array_pod_sort(Relocs.begin(), Relocs.end());
3400b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
341a894c8e34453493a9d3fb2ffbbc21151c3965b63Benjamin Kramer    // Disassemble symbol by symbol.
3420b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    for (unsigned SymIdx = 0; SymIdx != Symbols.size(); SymIdx++) {
343481837a743be2bd4723d96f304abba93140dc206Owen Anderson      StringRef SymName;
344481837a743be2bd4723d96f304abba93140dc206Owen Anderson      Symbols[SymIdx].getName(SymName);
345481837a743be2bd4723d96f304abba93140dc206Owen Anderson
346481837a743be2bd4723d96f304abba93140dc206Owen Anderson      SymbolRef::Type ST;
347481837a743be2bd4723d96f304abba93140dc206Owen Anderson      Symbols[SymIdx].getType(ST);
348481837a743be2bd4723d96f304abba93140dc206Owen Anderson      if (ST != SymbolRef::ST_Function)
349481837a743be2bd4723d96f304abba93140dc206Owen Anderson        continue;
350481837a743be2bd4723d96f304abba93140dc206Owen Anderson
351a894c8e34453493a9d3fb2ffbbc21151c3965b63Benjamin Kramer      // Make sure the symbol is defined in this section.
352481837a743be2bd4723d96f304abba93140dc206Owen Anderson      bool containsSym = false;
353481837a743be2bd4723d96f304abba93140dc206Owen Anderson      Sections[SectIdx].containsSymbol(Symbols[SymIdx], containsSym);
354481837a743be2bd4723d96f304abba93140dc206Owen Anderson      if (!containsSym)
3550b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        continue;
3560b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
357a894c8e34453493a9d3fb2ffbbc21151c3965b63Benjamin Kramer      // Start at the address of the symbol relative to the section's address.
358ec8eac6d8b70234b2dfee623190d609e17206bcaCameron Zwarich      uint64_t SectionAddress = 0;
359481837a743be2bd4723d96f304abba93140dc206Owen Anderson      uint64_t Start = 0;
360ec8eac6d8b70234b2dfee623190d609e17206bcaCameron Zwarich      Sections[SectIdx].getAddress(SectionAddress);
361b0436a73054fe676b216a0cf872d1fc433125c62Danil Malyshev      Symbols[SymIdx].getAddress(Start);
362ec8eac6d8b70234b2dfee623190d609e17206bcaCameron Zwarich      Start -= SectionAddress;
363481837a743be2bd4723d96f304abba93140dc206Owen Anderson
364a894c8e34453493a9d3fb2ffbbc21151c3965b63Benjamin Kramer      // Stop disassembling either at the beginning of the next symbol or at
365a894c8e34453493a9d3fb2ffbbc21151c3965b63Benjamin Kramer      // the end of the section.
36641854aea66ade4dea16a80bc8ef7ddf6c379d21fKevin Enderby      bool containsNextSym = false;
367481837a743be2bd4723d96f304abba93140dc206Owen Anderson      uint64_t NextSym = 0;
368481837a743be2bd4723d96f304abba93140dc206Owen Anderson      uint64_t NextSymIdx = SymIdx+1;
369481837a743be2bd4723d96f304abba93140dc206Owen Anderson      while (Symbols.size() > NextSymIdx) {
370481837a743be2bd4723d96f304abba93140dc206Owen Anderson        SymbolRef::Type NextSymType;
371481837a743be2bd4723d96f304abba93140dc206Owen Anderson        Symbols[NextSymIdx].getType(NextSymType);
372481837a743be2bd4723d96f304abba93140dc206Owen Anderson        if (NextSymType == SymbolRef::ST_Function) {
373481837a743be2bd4723d96f304abba93140dc206Owen Anderson          Sections[SectIdx].containsSymbol(Symbols[NextSymIdx],
374481837a743be2bd4723d96f304abba93140dc206Owen Anderson                                           containsNextSym);
375b0436a73054fe676b216a0cf872d1fc433125c62Danil Malyshev          Symbols[NextSymIdx].getAddress(NextSym);
376ec8eac6d8b70234b2dfee623190d609e17206bcaCameron Zwarich          NextSym -= SectionAddress;
377481837a743be2bd4723d96f304abba93140dc206Owen Anderson          break;
378481837a743be2bd4723d96f304abba93140dc206Owen Anderson        }
379481837a743be2bd4723d96f304abba93140dc206Owen Anderson        ++NextSymIdx;
380481837a743be2bd4723d96f304abba93140dc206Owen Anderson      }
3810b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
382481837a743be2bd4723d96f304abba93140dc206Owen Anderson      uint64_t SectSize;
383481837a743be2bd4723d96f304abba93140dc206Owen Anderson      Sections[SectIdx].getSize(SectSize);
384481837a743be2bd4723d96f304abba93140dc206Owen Anderson      uint64_t End = containsNextSym ?  NextSym : SectSize;
385481837a743be2bd4723d96f304abba93140dc206Owen Anderson      uint64_t Size;
3860b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
3870b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer      symbolTableWorked = true;
3880b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
389ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha      outs() << SymName << ":\n";
390ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha      DILineInfo lastLine;
391ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha      for (uint64_t Index = Start; Index < End; Index += Size) {
392ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha        MCInst Inst;
393ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha
39454154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby        uint64_t SectAddress = 0;
39554154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby        Sections[SectIdx].getAddress(SectAddress);
39654154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby        outs() << format("%8" PRIx64 ":\t", SectAddress + Index);
39754154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby
39854154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby        // Check the data in code table here to see if this is data not an
39954154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby        // instruction to be disassembled.
40054154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby        DiceTable Dice;
40154154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby        Dice.push_back(std::make_pair(SectAddress + Index, DiceRef()));
40254154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby        dice_table_iterator DTI = std::search(Dices.begin(), Dices.end(),
40354154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby                                              Dice.begin(), Dice.end(),
40454154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby                                              compareDiceTableEntries);
40554154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby        if (DTI != Dices.end()){
40654154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby          uint16_t Length;
40754154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby          DTI->second.getLength(Length);
40854154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby          DumpBytes(StringRef(Bytes.data() + Index, Length));
40954154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby          uint16_t Kind;
41054154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby          DTI->second.getKind(Kind);
41154154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby          DumpDataInCode(Bytes.data() + Index, Length, Kind);
41254154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby          continue;
41354154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby        }
41454154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby
415ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha        if (DisAsm->getInstruction(Inst, Size, memoryObject, Index,
416ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha                                   DebugOut, nulls())) {
417ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha          DumpBytes(StringRef(Bytes.data() + Index, Size));
418ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha          IP->printInst(&Inst, outs(), "");
419ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha
420ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha          // Print debug info.
421ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha          if (diContext) {
422ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha            DILineInfo dli =
423ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha              diContext->getLineInfoForAddress(SectAddress + Index);
424ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha            // Print valid line info if it changed.
425dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            if (dli != lastLine && dli.Line != 0)
426dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines              outs() << "\t## " << dli.FileName << ':' << dli.Line << ':'
427dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                     << dli.Column;
428ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha            lastLine = dli;
4290b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          }
430ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha          outs() << "\n";
431ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha        } else {
432ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha          errs() << "llvm-objdump: warning: invalid instruction encoding\n";
433ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha          if (Size == 0)
434ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha            Size = 1; // skip illegible bytes
4350b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        }
4360b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer      }
4370b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    }
438ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha    if (!symbolTableWorked) {
43959c15e920c9873804f3150d0c13357696f09e300Kevin Enderby      // Reading the symbol table didn't work, disassemble the whole section.
44059c15e920c9873804f3150d0c13357696f09e300Kevin Enderby      uint64_t SectAddress;
44159c15e920c9873804f3150d0c13357696f09e300Kevin Enderby      Sections[SectIdx].getAddress(SectAddress);
44259c15e920c9873804f3150d0c13357696f09e300Kevin Enderby      uint64_t SectSize;
44359c15e920c9873804f3150d0c13357696f09e300Kevin Enderby      Sections[SectIdx].getSize(SectSize);
44459c15e920c9873804f3150d0c13357696f09e300Kevin Enderby      uint64_t InstSize;
44559c15e920c9873804f3150d0c13357696f09e300Kevin Enderby      for (uint64_t Index = 0; Index < SectSize; Index += InstSize) {
446f59083cc029b1f09dec7cc62de070846b2c55bb8Bill Wendling        MCInst Inst;
447f59083cc029b1f09dec7cc62de070846b2c55bb8Bill Wendling
448f59083cc029b1f09dec7cc62de070846b2c55bb8Bill Wendling        if (DisAsm->getInstruction(Inst, InstSize, memoryObject, Index,
449f59083cc029b1f09dec7cc62de070846b2c55bb8Bill Wendling                                   DebugOut, nulls())) {
450f59083cc029b1f09dec7cc62de070846b2c55bb8Bill Wendling          outs() << format("%8" PRIx64 ":\t", SectAddress + Index);
451f59083cc029b1f09dec7cc62de070846b2c55bb8Bill Wendling          DumpBytes(StringRef(Bytes.data() + Index, InstSize));
452f59083cc029b1f09dec7cc62de070846b2c55bb8Bill Wendling          IP->printInst(&Inst, outs(), "");
453f59083cc029b1f09dec7cc62de070846b2c55bb8Bill Wendling          outs() << "\n";
454f59083cc029b1f09dec7cc62de070846b2c55bb8Bill Wendling        } else {
455f59083cc029b1f09dec7cc62de070846b2c55bb8Bill Wendling          errs() << "llvm-objdump: warning: invalid instruction encoding\n";
456f59083cc029b1f09dec7cc62de070846b2c55bb8Bill Wendling          if (InstSize == 0)
457f59083cc029b1f09dec7cc62de070846b2c55bb8Bill Wendling            InstSize = 1; // skip illegible bytes
458f59083cc029b1f09dec7cc62de070846b2c55bb8Bill Wendling        }
45959c15e920c9873804f3150d0c13357696f09e300Kevin Enderby      }
46059c15e920c9873804f3150d0c13357696f09e300Kevin Enderby    }
4610b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  }
4620b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer}
463