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/OwningPtr.h"
160b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include "llvm/ADT/STLExtras.h"
17ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha#include "llvm/ADT/StringExtras.h"
18f010c464a11444733ec67e31aace8bcebeaf2588Chandler Carruth#include "llvm/ADT/Triple.h"
198c93097c4c5e6dddc8c239295a1b42217b082ad3Benjamin Kramer#include "llvm/DebugInfo/DIContext.h"
200b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include "llvm/MC/MCAsmInfo.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 "llvm/Support/system_error.h"
410b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include <algorithm>
420b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include <cstring>
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";
680b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  return 0;
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) {
10754154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby  case macho::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;
12854154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby  case macho::JumpTable8:
12954154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby    Value = bytes[0];
13054154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby    outs() << "\t.byte " << Value << "\t@ KIND_JUMP_TABLE8";
13154154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby    break;
13254154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby  case macho::JumpTable16:
13354154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby    Value = bytes[1] << 8 |
13454154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby            bytes[0];
13554154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby    outs() << "\t.short " << Value << "\t@ KIND_JUMP_TABLE16";
13654154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby    break;
13754154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby  case macho::JumpTable32:
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
150da2a2372c6ae715befae7f086afe769dd80814f3Rafael Espindolastatic void
151fd7aa38e304a09fa0ef51b85b773b649b7e58c5eRafael EspindolagetSectionsAndSymbols(const macho::Header Header,
152fd7aa38e304a09fa0ef51b85b773b649b7e58c5eRafael Espindola                      MachOObjectFile *MachOObj,
153da2a2372c6ae715befae7f086afe769dd80814f3Rafael Espindola                      std::vector<SectionRef> &Sections,
154da2a2372c6ae715befae7f086afe769dd80814f3Rafael Espindola                      std::vector<SymbolRef> &Symbols,
15554154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby                      SmallVectorImpl<uint64_t> &FoundFns,
15654154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby                      uint64_t &BaseSegmentAddress) {
157481837a743be2bd4723d96f304abba93140dc206Owen Anderson  error_code ec;
158481837a743be2bd4723d96f304abba93140dc206Owen Anderson  for (symbol_iterator SI = MachOObj->begin_symbols(),
159481837a743be2bd4723d96f304abba93140dc206Owen Anderson       SE = MachOObj->end_symbols(); SI != SE; SI.increment(ec))
160481837a743be2bd4723d96f304abba93140dc206Owen Anderson    Symbols.push_back(*SI);
161481837a743be2bd4723d96f304abba93140dc206Owen Anderson
162481837a743be2bd4723d96f304abba93140dc206Owen Anderson  for (section_iterator SI = MachOObj->begin_sections(),
163481837a743be2bd4723d96f304abba93140dc206Owen Anderson       SE = MachOObj->end_sections(); SI != SE; SI.increment(ec)) {
164481837a743be2bd4723d96f304abba93140dc206Owen Anderson    SectionRef SR = *SI;
165481837a743be2bd4723d96f304abba93140dc206Owen Anderson    StringRef SectName;
166481837a743be2bd4723d96f304abba93140dc206Owen Anderson    SR.getName(SectName);
167481837a743be2bd4723d96f304abba93140dc206Owen Anderson    Sections.push_back(*SI);
168481837a743be2bd4723d96f304abba93140dc206Owen Anderson  }
1698c93097c4c5e6dddc8c239295a1b42217b082ad3Benjamin Kramer
170fd7aa38e304a09fa0ef51b85b773b649b7e58c5eRafael Espindola  MachOObjectFile::LoadCommandInfo Command =
171fd7aa38e304a09fa0ef51b85b773b649b7e58c5eRafael Espindola    MachOObj->getFirstLoadCommandInfo();
17254154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby  bool BaseSegmentAddressSet = false;
173db5f9270207292b62ea847560c5dd4e9873b57f5Rafael Espindola  for (unsigned i = 0; ; ++i) {
174fd7aa38e304a09fa0ef51b85b773b649b7e58c5eRafael Espindola    if (Command.C.Type == macho::LCT_FunctionStarts) {
1758c93097c4c5e6dddc8c239295a1b42217b082ad3Benjamin Kramer      // We found a function starts segment, parse the addresses for later
1768c93097c4c5e6dddc8c239295a1b42217b082ad3Benjamin Kramer      // consumption.
177fd7aa38e304a09fa0ef51b85b773b649b7e58c5eRafael Espindola      macho::LinkeditDataLoadCommand LLC =
178fd7aa38e304a09fa0ef51b85b773b649b7e58c5eRafael Espindola        MachOObj->getLinkeditDataLoadCommand(Command);
1798c93097c4c5e6dddc8c239295a1b42217b082ad3Benjamin Kramer
180fd7aa38e304a09fa0ef51b85b773b649b7e58c5eRafael Espindola      MachOObj->ReadULEB128s(LLC.DataOffset, FoundFns);
181afbaf48fc4a645a95737ea81e2e0fde47a6150baBenjamin Kramer    }
18254154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby    else if (Command.C.Type == macho::LCT_Segment) {
18354154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby      macho::SegmentLoadCommand SLC =
18454154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby        MachOObj->getSegmentLoadCommand(Command);
18554154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby      StringRef SegName = SLC.Name;
18654154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby      if(!BaseSegmentAddressSet && SegName != "__PAGEZERO") {
18754154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby        BaseSegmentAddressSet = true;
18854154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby        BaseSegmentAddress = SLC.VMAddress;
18954154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby      }
19054154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby    }
191db5f9270207292b62ea847560c5dd4e9873b57f5Rafael Espindola
192db5f9270207292b62ea847560c5dd4e9873b57f5Rafael Espindola    if (i == Header.NumLoadCommands - 1)
193db5f9270207292b62ea847560c5dd4e9873b57f5Rafael Espindola      break;
194db5f9270207292b62ea847560c5dd4e9873b57f5Rafael Espindola    else
195db5f9270207292b62ea847560c5dd4e9873b57f5Rafael Espindola      Command = MachOObj->getNextLoadCommandInfo(Command);
196afbaf48fc4a645a95737ea81e2e0fde47a6150baBenjamin Kramer  }
1978c93097c4c5e6dddc8c239295a1b42217b082ad3Benjamin Kramer}
1988c93097c4c5e6dddc8c239295a1b42217b082ad3Benjamin Kramer
199da2a2372c6ae715befae7f086afe769dd80814f3Rafael Espindolastatic void DisassembleInputMachO2(StringRef Filename,
200fd7aa38e304a09fa0ef51b85b773b649b7e58c5eRafael Espindola                                   MachOObjectFile *MachOOF);
201da2a2372c6ae715befae7f086afe769dd80814f3Rafael Espindola
2020b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramervoid llvm::DisassembleInputMachO(StringRef Filename) {
2030b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  OwningPtr<MemoryBuffer> Buff;
2040b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
2050b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  if (error_code ec = MemoryBuffer::getFileOrSTDIN(Filename, Buff)) {
2060b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    errs() << "llvm-objdump: " << Filename << ": " << ec.message() << "\n";
2070b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    return;
2080b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  }
2090b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
210fd7aa38e304a09fa0ef51b85b773b649b7e58c5eRafael Espindola  OwningPtr<MachOObjectFile> MachOOF(static_cast<MachOObjectFile*>(
211481837a743be2bd4723d96f304abba93140dc206Owen Anderson        ObjectFile::createMachOObjectFile(Buff.take())));
2120b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
213fd7aa38e304a09fa0ef51b85b773b649b7e58c5eRafael Espindola  DisassembleInputMachO2(Filename, MachOOF.get());
214da2a2372c6ae715befae7f086afe769dd80814f3Rafael Espindola}
215da2a2372c6ae715befae7f086afe769dd80814f3Rafael Espindola
216da2a2372c6ae715befae7f086afe769dd80814f3Rafael Espindolastatic void DisassembleInputMachO2(StringRef Filename,
217fd7aa38e304a09fa0ef51b85b773b649b7e58c5eRafael Espindola                                   MachOObjectFile *MachOOF) {
218da2a2372c6ae715befae7f086afe769dd80814f3Rafael Espindola  const Target *TheTarget = GetTarget(MachOOF);
2190b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  if (!TheTarget) {
2200b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    // GetTarget prints out stuff.
2210b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    return;
2220b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  }
223d226ed71f24f2db200e3751e05b82c7700514116Benjamin Kramer  OwningPtr<const MCInstrInfo> InstrInfo(TheTarget->createMCInstrInfo());
2240b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  OwningPtr<MCInstrAnalysis>
225d226ed71f24f2db200e3751e05b82c7700514116Benjamin Kramer    InstrAnalysis(TheTarget->createMCInstrAnalysis(InstrInfo.get()));
2260b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
2270b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  // Set up disassembler.
2284a971705bc6030dc2e4338b3cd5cffa2e0f88b7bRafael Espindola  OwningPtr<const MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TripleName));
2294a971705bc6030dc2e4338b3cd5cffa2e0f88b7bRafael Espindola  OwningPtr<const MCAsmInfo> AsmInfo(
2304a971705bc6030dc2e4338b3cd5cffa2e0f88b7bRafael Espindola      TheTarget->createMCAsmInfo(*MRI, TripleName));
2310b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  OwningPtr<const MCSubtargetInfo>
2320b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    STI(TheTarget->createMCSubtargetInfo(TripleName, "", ""));
2330b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  OwningPtr<const MCDisassembler> DisAsm(TheTarget->createMCDisassembler(*STI));
2340b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  int AsmPrinterVariant = AsmInfo->getAssemblerDialect();
23517463b3ef1a3d39b10619254f12e806c8c43f9e7Craig Topper  OwningPtr<MCInstPrinter>
23617463b3ef1a3d39b10619254f12e806c8c43f9e7Craig Topper    IP(TheTarget->createMCInstPrinter(AsmPrinterVariant, *AsmInfo, *InstrInfo,
23717463b3ef1a3d39b10619254f12e806c8c43f9e7Craig Topper                                      *MRI, *STI));
238a894c8e34453493a9d3fb2ffbbc21151c3965b63Benjamin Kramer
239a894c8e34453493a9d3fb2ffbbc21151c3965b63Benjamin Kramer  if (!InstrAnalysis || !AsmInfo || !STI || !DisAsm || !IP) {
2403773fb46ba530f69530d1c4bafb7885528a27391Michael J. Spencer    errs() << "error: couldn't initialize disassembler for target "
241a894c8e34453493a9d3fb2ffbbc21151c3965b63Benjamin Kramer           << TripleName << '\n';
2420b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    return;
2430b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  }
2440b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
245a894c8e34453493a9d3fb2ffbbc21151c3965b63Benjamin Kramer  outs() << '\n' << Filename << ":\n\n";
2460b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
247fd7aa38e304a09fa0ef51b85b773b649b7e58c5eRafael Espindola  macho::Header Header = MachOOF->getHeader();
2480b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
249ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  // FIXME: FoundFns isn't used anymore. Using symbols/LC_FUNCTION_STARTS to
250ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  // determine function locations will eventually go in MCObjectDisassembler.
251ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  // FIXME: Using the -cfg command line option, this code used to be able to
252ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  // annotate relocations with the referenced symbol's name, and if this was
253ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  // inside a __[cf]string section, the data it points to. This is now replaced
254ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha  // by the upcoming MCSymbolizer, which needs the appropriate setup done above.
255481837a743be2bd4723d96f304abba93140dc206Owen Anderson  std::vector<SectionRef> Sections;
256481837a743be2bd4723d96f304abba93140dc206Owen Anderson  std::vector<SymbolRef> Symbols;
2570b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  SmallVector<uint64_t, 8> FoundFns;
25854154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby  uint64_t BaseSegmentAddress;
2590b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
26054154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby  getSectionsAndSymbols(Header, MachOOF, Sections, Symbols, FoundFns,
26154154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby                        BaseSegmentAddress);
2620b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
2638c93097c4c5e6dddc8c239295a1b42217b082ad3Benjamin Kramer  // Make a copy of the unsorted symbol list. FIXME: duplication
264481837a743be2bd4723d96f304abba93140dc206Owen Anderson  std::vector<SymbolRef> UnsortedSymbols(Symbols);
2650b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  // Sort the symbols by address, just in case they didn't come in that way.
266481837a743be2bd4723d96f304abba93140dc206Owen Anderson  std::sort(Symbols.begin(), Symbols.end(), SymbolSorter());
2670b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
26854154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby  // Build a data in code table that is sorted on by the address of each entry.
26954154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby  uint64_t BaseAddress = 0;
27054154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby  if (Header.FileType == macho::HFT_Object)
27154154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby    Sections[0].getAddress(BaseAddress);
27254154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby  else
27354154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby    BaseAddress = BaseSegmentAddress;
27454154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby  DiceTable Dices;
27554154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby  error_code ec;
27654154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby  for (dice_iterator DI = MachOOF->begin_dices(), DE = MachOOF->end_dices();
27754154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby       DI != DE; DI.increment(ec)){
27854154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby    uint32_t Offset;
27954154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby    DI->getOffset(Offset);
28054154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby    Dices.push_back(std::make_pair(BaseAddress + Offset, *DI));
28154154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby  }
28254154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby  array_pod_sort(Dices.begin(), Dices.end());
28354154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby
2840b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#ifndef NDEBUG
2850b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  raw_ostream &DebugOut = DebugFlag ? dbgs() : nulls();
2860b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#else
2870b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  raw_ostream &DebugOut = nulls();
2880b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#endif
2890b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
2908c93097c4c5e6dddc8c239295a1b42217b082ad3Benjamin Kramer  OwningPtr<DIContext> diContext;
291da2a2372c6ae715befae7f086afe769dd80814f3Rafael Espindola  ObjectFile *DbgObj = MachOOF;
2928c93097c4c5e6dddc8c239295a1b42217b082ad3Benjamin Kramer  // Try to find debug info and set up the DIContext for it.
2938c93097c4c5e6dddc8c239295a1b42217b082ad3Benjamin Kramer  if (UseDbg) {
2948c93097c4c5e6dddc8c239295a1b42217b082ad3Benjamin Kramer    // A separate DSym file path was specified, parse it as a macho file,
2958c93097c4c5e6dddc8c239295a1b42217b082ad3Benjamin Kramer    // get the sections and supply it to the section name parsing machinery.
2968c93097c4c5e6dddc8c239295a1b42217b082ad3Benjamin Kramer    if (!DSYMFile.empty()) {
2978c93097c4c5e6dddc8c239295a1b42217b082ad3Benjamin Kramer      OwningPtr<MemoryBuffer> Buf;
298dd5af27a74a01f0d03356cea15d3a403f4964f8bRafael Espindola      if (error_code ec = MemoryBuffer::getFileOrSTDIN(DSYMFile, Buf)) {
2998c93097c4c5e6dddc8c239295a1b42217b082ad3Benjamin Kramer        errs() << "llvm-objdump: " << Filename << ": " << ec.message() << '\n';
3008c93097c4c5e6dddc8c239295a1b42217b082ad3Benjamin Kramer        return;
3018c93097c4c5e6dddc8c239295a1b42217b082ad3Benjamin Kramer      }
302d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher      DbgObj = ObjectFile::createMachOObjectFile(Buf.take());
3038c93097c4c5e6dddc8c239295a1b42217b082ad3Benjamin Kramer    }
3048c93097c4c5e6dddc8c239295a1b42217b082ad3Benjamin Kramer
305d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher    // Setup the DIContext
306d1726a4580f3dc42e2debbfea41acb9e815c06beEric Christopher    diContext.reset(DIContext::getDWARFContext(DbgObj));
3078c93097c4c5e6dddc8c239295a1b42217b082ad3Benjamin Kramer  }
3088c93097c4c5e6dddc8c239295a1b42217b082ad3Benjamin Kramer
3090b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  for (unsigned SectIdx = 0; SectIdx != Sections.size(); SectIdx++) {
310ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha
311ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha    bool SectIsText = false;
312ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha    Sections[SectIdx].isText(SectIsText);
313ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha    if (SectIsText == false)
314ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha      continue;
315ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha
316481837a743be2bd4723d96f304abba93140dc206Owen Anderson    StringRef SectName;
317481837a743be2bd4723d96f304abba93140dc206Owen Anderson    if (Sections[SectIdx].getName(SectName) ||
318cef81b37c77978cd4dddb4a5ad13564793ded155Rafael Espindola        SectName != "__text")
319a894c8e34453493a9d3fb2ffbbc21151c3965b63Benjamin Kramer      continue; // Skip non-text sections
3200b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
321cef81b37c77978cd4dddb4a5ad13564793ded155Rafael Espindola    DataRefImpl DR = Sections[SectIdx].getRawDataRefImpl();
322ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha
323f16c2bb320f4d5b33dfaf8df8865f547e6d66005Rafael Espindola    StringRef SegmentName = MachOOF->getSectionFinalSegmentName(DR);
324f16c2bb320f4d5b33dfaf8df8865f547e6d66005Rafael Espindola    if (SegmentName != "__TEXT")
325cef81b37c77978cd4dddb4a5ad13564793ded155Rafael Espindola      continue;
326cef81b37c77978cd4dddb4a5ad13564793ded155Rafael Espindola
327481837a743be2bd4723d96f304abba93140dc206Owen Anderson    StringRef Bytes;
328481837a743be2bd4723d96f304abba93140dc206Owen Anderson    Sections[SectIdx].getContents(Bytes);
3290b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    StringRefMemoryObject memoryObject(Bytes);
3300b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    bool symbolTableWorked = false;
3310b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
332a894c8e34453493a9d3fb2ffbbc21151c3965b63Benjamin Kramer    // Parse relocations.
3337d3f8b8e48854b890762ccb96f7817568541732bOwen Anderson    std::vector<std::pair<uint64_t, SymbolRef> > Relocs;
334481837a743be2bd4723d96f304abba93140dc206Owen Anderson    error_code ec;
335481837a743be2bd4723d96f304abba93140dc206Owen Anderson    for (relocation_iterator RI = Sections[SectIdx].begin_relocations(),
336481837a743be2bd4723d96f304abba93140dc206Owen Anderson         RE = Sections[SectIdx].end_relocations(); RI != RE; RI.increment(ec)) {
337481837a743be2bd4723d96f304abba93140dc206Owen Anderson      uint64_t RelocOffset, SectionAddress;
338956ca7265c697107708468b7e1b2fd21f4185baeRafael Espindola      RI->getOffset(RelocOffset);
339481837a743be2bd4723d96f304abba93140dc206Owen Anderson      Sections[SectIdx].getAddress(SectionAddress);
340481837a743be2bd4723d96f304abba93140dc206Owen Anderson      RelocOffset -= SectionAddress;
341481837a743be2bd4723d96f304abba93140dc206Owen Anderson
3426c1202c459ffa6d693ad92fa84e43902bc780bcaRafael Espindola      symbol_iterator RelocSym = RI->getSymbol();
343481837a743be2bd4723d96f304abba93140dc206Owen Anderson
3446c1202c459ffa6d693ad92fa84e43902bc780bcaRafael Espindola      Relocs.push_back(std::make_pair(RelocOffset, *RelocSym));
3450b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    }
3460b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    array_pod_sort(Relocs.begin(), Relocs.end());
3470b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
348a894c8e34453493a9d3fb2ffbbc21151c3965b63Benjamin Kramer    // Disassemble symbol by symbol.
3490b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    for (unsigned SymIdx = 0; SymIdx != Symbols.size(); SymIdx++) {
350481837a743be2bd4723d96f304abba93140dc206Owen Anderson      StringRef SymName;
351481837a743be2bd4723d96f304abba93140dc206Owen Anderson      Symbols[SymIdx].getName(SymName);
352481837a743be2bd4723d96f304abba93140dc206Owen Anderson
353481837a743be2bd4723d96f304abba93140dc206Owen Anderson      SymbolRef::Type ST;
354481837a743be2bd4723d96f304abba93140dc206Owen Anderson      Symbols[SymIdx].getType(ST);
355481837a743be2bd4723d96f304abba93140dc206Owen Anderson      if (ST != SymbolRef::ST_Function)
356481837a743be2bd4723d96f304abba93140dc206Owen Anderson        continue;
357481837a743be2bd4723d96f304abba93140dc206Owen Anderson
358a894c8e34453493a9d3fb2ffbbc21151c3965b63Benjamin Kramer      // Make sure the symbol is defined in this section.
359481837a743be2bd4723d96f304abba93140dc206Owen Anderson      bool containsSym = false;
360481837a743be2bd4723d96f304abba93140dc206Owen Anderson      Sections[SectIdx].containsSymbol(Symbols[SymIdx], containsSym);
361481837a743be2bd4723d96f304abba93140dc206Owen Anderson      if (!containsSym)
3620b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        continue;
3630b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
364a894c8e34453493a9d3fb2ffbbc21151c3965b63Benjamin Kramer      // Start at the address of the symbol relative to the section's address.
365ec8eac6d8b70234b2dfee623190d609e17206bcaCameron Zwarich      uint64_t SectionAddress = 0;
366481837a743be2bd4723d96f304abba93140dc206Owen Anderson      uint64_t Start = 0;
367ec8eac6d8b70234b2dfee623190d609e17206bcaCameron Zwarich      Sections[SectIdx].getAddress(SectionAddress);
368b0436a73054fe676b216a0cf872d1fc433125c62Danil Malyshev      Symbols[SymIdx].getAddress(Start);
369ec8eac6d8b70234b2dfee623190d609e17206bcaCameron Zwarich      Start -= SectionAddress;
370481837a743be2bd4723d96f304abba93140dc206Owen Anderson
371a894c8e34453493a9d3fb2ffbbc21151c3965b63Benjamin Kramer      // Stop disassembling either at the beginning of the next symbol or at
372a894c8e34453493a9d3fb2ffbbc21151c3965b63Benjamin Kramer      // the end of the section.
37341854aea66ade4dea16a80bc8ef7ddf6c379d21fKevin Enderby      bool containsNextSym = false;
374481837a743be2bd4723d96f304abba93140dc206Owen Anderson      uint64_t NextSym = 0;
375481837a743be2bd4723d96f304abba93140dc206Owen Anderson      uint64_t NextSymIdx = SymIdx+1;
376481837a743be2bd4723d96f304abba93140dc206Owen Anderson      while (Symbols.size() > NextSymIdx) {
377481837a743be2bd4723d96f304abba93140dc206Owen Anderson        SymbolRef::Type NextSymType;
378481837a743be2bd4723d96f304abba93140dc206Owen Anderson        Symbols[NextSymIdx].getType(NextSymType);
379481837a743be2bd4723d96f304abba93140dc206Owen Anderson        if (NextSymType == SymbolRef::ST_Function) {
380481837a743be2bd4723d96f304abba93140dc206Owen Anderson          Sections[SectIdx].containsSymbol(Symbols[NextSymIdx],
381481837a743be2bd4723d96f304abba93140dc206Owen Anderson                                           containsNextSym);
382b0436a73054fe676b216a0cf872d1fc433125c62Danil Malyshev          Symbols[NextSymIdx].getAddress(NextSym);
383ec8eac6d8b70234b2dfee623190d609e17206bcaCameron Zwarich          NextSym -= SectionAddress;
384481837a743be2bd4723d96f304abba93140dc206Owen Anderson          break;
385481837a743be2bd4723d96f304abba93140dc206Owen Anderson        }
386481837a743be2bd4723d96f304abba93140dc206Owen Anderson        ++NextSymIdx;
387481837a743be2bd4723d96f304abba93140dc206Owen Anderson      }
3880b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
389481837a743be2bd4723d96f304abba93140dc206Owen Anderson      uint64_t SectSize;
390481837a743be2bd4723d96f304abba93140dc206Owen Anderson      Sections[SectIdx].getSize(SectSize);
391481837a743be2bd4723d96f304abba93140dc206Owen Anderson      uint64_t End = containsNextSym ?  NextSym : SectSize;
392481837a743be2bd4723d96f304abba93140dc206Owen Anderson      uint64_t Size;
3930b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
3940b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer      symbolTableWorked = true;
3950b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
396ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha      outs() << SymName << ":\n";
397ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha      DILineInfo lastLine;
398ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha      for (uint64_t Index = Start; Index < End; Index += Size) {
399ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha        MCInst Inst;
400ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha
40154154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby        uint64_t SectAddress = 0;
40254154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby        Sections[SectIdx].getAddress(SectAddress);
40354154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby        outs() << format("%8" PRIx64 ":\t", SectAddress + Index);
40454154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby
40554154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby        // Check the data in code table here to see if this is data not an
40654154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby        // instruction to be disassembled.
40754154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby        DiceTable Dice;
40854154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby        Dice.push_back(std::make_pair(SectAddress + Index, DiceRef()));
40954154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby        dice_table_iterator DTI = std::search(Dices.begin(), Dices.end(),
41054154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby                                              Dice.begin(), Dice.end(),
41154154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby                                              compareDiceTableEntries);
41254154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby        if (DTI != Dices.end()){
41354154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby          uint16_t Length;
41454154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby          DTI->second.getLength(Length);
41554154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby          DumpBytes(StringRef(Bytes.data() + Index, Length));
41654154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby          uint16_t Kind;
41754154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby          DTI->second.getKind(Kind);
41854154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby          DumpDataInCode(Bytes.data() + Index, Length, Kind);
41954154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby          continue;
42054154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby        }
42154154f3bf1ae3d2dfd68cc9474cad061b3338a40Kevin Enderby
422ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha        if (DisAsm->getInstruction(Inst, Size, memoryObject, Index,
423ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha                                   DebugOut, nulls())) {
424ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha          DumpBytes(StringRef(Bytes.data() + Index, Size));
425ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha          IP->printInst(&Inst, outs(), "");
426ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha
427ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha          // Print debug info.
428ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha          if (diContext) {
429ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha            DILineInfo dli =
430ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha              diContext->getLineInfoForAddress(SectAddress + Index);
431ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha            // Print valid line info if it changed.
432ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha            if (dli != lastLine && dli.getLine() != 0)
433ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha              outs() << "\t## " << dli.getFileName() << ':'
434ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha                << dli.getLine() << ':' << dli.getColumn();
435ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha            lastLine = dli;
4360b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          }
437ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha          outs() << "\n";
438ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha        } else {
439ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha          errs() << "llvm-objdump: warning: invalid instruction encoding\n";
440ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha          if (Size == 0)
441ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha            Size = 1; // skip illegible bytes
4420b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        }
4430b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer      }
4440b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    }
445ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha    if (!symbolTableWorked) {
44659c15e920c9873804f3150d0c13357696f09e300Kevin Enderby      // Reading the symbol table didn't work, disassemble the whole section.
44759c15e920c9873804f3150d0c13357696f09e300Kevin Enderby      uint64_t SectAddress;
44859c15e920c9873804f3150d0c13357696f09e300Kevin Enderby      Sections[SectIdx].getAddress(SectAddress);
44959c15e920c9873804f3150d0c13357696f09e300Kevin Enderby      uint64_t SectSize;
45059c15e920c9873804f3150d0c13357696f09e300Kevin Enderby      Sections[SectIdx].getSize(SectSize);
45159c15e920c9873804f3150d0c13357696f09e300Kevin Enderby      uint64_t InstSize;
45259c15e920c9873804f3150d0c13357696f09e300Kevin Enderby      for (uint64_t Index = 0; Index < SectSize; Index += InstSize) {
453f59083cc029b1f09dec7cc62de070846b2c55bb8Bill Wendling        MCInst Inst;
454f59083cc029b1f09dec7cc62de070846b2c55bb8Bill Wendling
455f59083cc029b1f09dec7cc62de070846b2c55bb8Bill Wendling        if (DisAsm->getInstruction(Inst, InstSize, memoryObject, Index,
456f59083cc029b1f09dec7cc62de070846b2c55bb8Bill Wendling                                   DebugOut, nulls())) {
457f59083cc029b1f09dec7cc62de070846b2c55bb8Bill Wendling          outs() << format("%8" PRIx64 ":\t", SectAddress + Index);
458f59083cc029b1f09dec7cc62de070846b2c55bb8Bill Wendling          DumpBytes(StringRef(Bytes.data() + Index, InstSize));
459f59083cc029b1f09dec7cc62de070846b2c55bb8Bill Wendling          IP->printInst(&Inst, outs(), "");
460f59083cc029b1f09dec7cc62de070846b2c55bb8Bill Wendling          outs() << "\n";
461f59083cc029b1f09dec7cc62de070846b2c55bb8Bill Wendling        } else {
462f59083cc029b1f09dec7cc62de070846b2c55bb8Bill Wendling          errs() << "llvm-objdump: warning: invalid instruction encoding\n";
463f59083cc029b1f09dec7cc62de070846b2c55bb8Bill Wendling          if (InstSize == 0)
464f59083cc029b1f09dec7cc62de070846b2c55bb8Bill Wendling            InstSize = 1; // skip illegible bytes
465f59083cc029b1f09dec7cc62de070846b2c55bb8Bill Wendling        }
46659c15e920c9873804f3150d0c13357696f09e300Kevin Enderby      }
46759c15e920c9873804f3150d0c13357696f09e300Kevin Enderby    }
4680b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  }
4690b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer}
470