MachODump.cpp revision 0b8b771e9f2f251460a6f200c45efe9d55640d60
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 "MCFunction.h"
160b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include "llvm/Support/MachO.h"
170b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include "llvm/Object/MachOObject.h"
180b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include "llvm/ADT/OwningPtr.h"
190b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include "llvm/ADT/Triple.h"
200b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include "llvm/ADT/STLExtras.h"
210b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include "llvm/MC/MCAsmInfo.h"
220b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include "llvm/MC/MCDisassembler.h"
230b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include "llvm/MC/MCInst.h"
240b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include "llvm/MC/MCInstPrinter.h"
250b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include "llvm/MC/MCInstrAnalysis.h"
260b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include "llvm/MC/MCInstrDesc.h"
270b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include "llvm/MC/MCInstrInfo.h"
280b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include "llvm/MC/MCSubtargetInfo.h"
290b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include "llvm/Support/CommandLine.h"
300b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include "llvm/Support/Debug.h"
310b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include "llvm/Support/Format.h"
320b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include "llvm/Support/GraphWriter.h"
330b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include "llvm/Support/MemoryBuffer.h"
340b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include "llvm/Support/TargetRegistry.h"
350b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include "llvm/Support/TargetSelect.h"
360b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include "llvm/Support/raw_ostream.h"
370b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include "llvm/Support/system_error.h"
380b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include <algorithm>
390b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include <cstring>
400b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramerusing namespace llvm;
410b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramerusing namespace object;
420b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
430b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramerstatic cl::opt<bool>
440b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  CFG("cfg", cl::desc("Create a CFG for every symbol in the object file and"
450b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer                      "write it to a graphviz file (MachO-only)"));
460b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
470b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramerstatic const Target *GetTarget(const MachOObject *MachOObj) {
480b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  // Figure out the target triple.
490b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  llvm::Triple TT("unknown-unknown-unknown");
500b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  switch (MachOObj->getHeader().CPUType) {
510b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  case llvm::MachO::CPUTypeI386:
520b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    TT.setArch(Triple::ArchType(Triple::x86));
530b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    break;
540b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  case llvm::MachO::CPUTypeX86_64:
550b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    TT.setArch(Triple::ArchType(Triple::x86_64));
560b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    break;
570b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  case llvm::MachO::CPUTypeARM:
580b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    TT.setArch(Triple::ArchType(Triple::arm));
590b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    break;
600b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  case llvm::MachO::CPUTypePowerPC:
610b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    TT.setArch(Triple::ArchType(Triple::ppc));
620b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    break;
630b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  case llvm::MachO::CPUTypePowerPC64:
640b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    TT.setArch(Triple::ArchType(Triple::ppc64));
650b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    break;
660b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  }
670b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
680b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  TripleName = TT.str();
690b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
700b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  // Get the target specific parser.
710b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  std::string Error;
720b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  const Target *TheTarget = TargetRegistry::lookupTarget(TripleName, Error);
730b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  if (TheTarget)
740b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    return TheTarget;
750b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
760b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  errs() << "llvm-objdump: error: unable to get target for '" << TripleName
770b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer         << "', see --version and --triple.\n";
780b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  return 0;
790b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer}
800b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
810b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramerstruct Section {
820b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  char Name[16];
830b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  uint64_t Address;
840b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  uint64_t Size;
850b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  uint32_t Offset;
860b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  uint32_t NumRelocs;
870b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  uint64_t RelocTableOffset;
880b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer};
890b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
900b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramerstruct Symbol {
910b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  uint64_t Value;
920b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  uint32_t StringIndex;
930b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  uint8_t SectionIndex;
940b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  bool operator<(const Symbol &RHS) const { return Value < RHS.Value; }
950b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer};
960b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
970b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramerstatic void DumpAddress(uint64_t Address, ArrayRef<Section> Sections,
980b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer                        MachOObject *MachOObj, raw_ostream &OS) {
990b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  for (unsigned i = 0; i != Sections.size(); ++i) {
1000b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    uint64_t addr = Address-Sections[i].Address;
1010b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    if (Sections[i].Address <= Address &&
1020b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        Sections[i].Address + Sections[i].Size > Address) {
1030b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer      StringRef bytes = MachOObj->getData(Sections[i].Offset,
1040b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer                                          Sections[i].Size);
1050b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer      if (!strcmp(Sections[i].Name, "__cstring"))
1060b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        OS << '"' << bytes.substr(addr, bytes.find('\0', addr)) << '"';
1070b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer      if (!strcmp(Sections[i].Name, "__cfstring"))
1080b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        OS << "@\"" << bytes.substr(addr, bytes.find('\0', addr)) << '"';
1090b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    }
1100b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  }
1110b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer}
1120b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
1130b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramervoid llvm::DisassembleInputMachO(StringRef Filename) {
1140b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  OwningPtr<MemoryBuffer> Buff;
1150b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
1160b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  if (error_code ec = MemoryBuffer::getFileOrSTDIN(Filename, Buff)) {
1170b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    errs() << "llvm-objdump: " << Filename << ": " << ec.message() << "\n";
1180b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    return;
1190b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  }
1200b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
1210b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  OwningPtr<MachOObject> MachOObj(MachOObject::LoadFromBuffer(Buff.take()));
1220b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
1230b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  const Target *TheTarget = GetTarget(MachOObj.get());
1240b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  if (!TheTarget) {
1250b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    // GetTarget prints out stuff.
1260b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    return;
1270b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  }
1280b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  const MCInstrInfo *InstrInfo = TheTarget->createMCInstrInfo();
1290b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  OwningPtr<MCInstrAnalysis>
1300b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    InstrAnalysis(TheTarget->createMCInstrAnalysis(InstrInfo));
1310b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
1320b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  // Set up disassembler.
1330b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  OwningPtr<const MCAsmInfo> AsmInfo(TheTarget->createMCAsmInfo(TripleName));
1340b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
1350b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  if (!AsmInfo) {
1360b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    errs() << "error: no assembly info for target " << TripleName << "\n";
1370b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    return;
1380b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  }
1390b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
1400b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  OwningPtr<const MCSubtargetInfo>
1410b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    STI(TheTarget->createMCSubtargetInfo(TripleName, "", ""));
1420b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
1430b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  if (!STI) {
1440b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    errs() << "error: no subtarget info for target " << TripleName << "\n";
1450b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    return;
1460b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  }
1470b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
1480b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  OwningPtr<const MCDisassembler> DisAsm(TheTarget->createMCDisassembler(*STI));
1490b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  if (!DisAsm) {
1500b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    errs() << "error: no disassembler for target " << TripleName << "\n";
1510b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    return;
1520b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  }
1530b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
1540b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  int AsmPrinterVariant = AsmInfo->getAssemblerDialect();
1550b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  OwningPtr<MCInstPrinter> IP(TheTarget->createMCInstPrinter(
1560b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        AsmPrinterVariant, *AsmInfo, *STI));
1570b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  if (!IP) {
1580b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    errs() << "error: no instruction printer for target " << TripleName << '\n';
1590b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    return;
1600b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  }
1610b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
1620b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  outs() << '\n';
1630b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  outs() << Filename << ":\n\n";
1640b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
1650b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  const macho::Header &Header = MachOObj->getHeader();
1660b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
1670b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  const MachOObject::LoadCommandInfo *SymtabLCI = 0;
1680b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  for (unsigned i = 0; i != Header.NumLoadCommands; ++i) {
1690b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    const MachOObject::LoadCommandInfo &LCI = MachOObj->getLoadCommandInfo(i);
1700b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    switch (LCI.Command.Type) {
1710b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    case macho::LCT_Symtab:
1720b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer      SymtabLCI = &LCI;
1730b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer      break;
1740b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    }
1750b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  }
1760b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
1770b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  // Read and register the symbol table data.
1780b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  InMemoryStruct<macho::SymtabLoadCommand> SymtabLC;
1790b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  MachOObj->ReadSymtabLoadCommand(*SymtabLCI, SymtabLC);
1800b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  MachOObj->RegisterStringTable(*SymtabLC);
1810b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
1820b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  std::vector<Section> Sections;
1830b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  std::vector<Symbol> Symbols;
1840b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  std::vector<Symbol> UnsortedSymbols; // FIXME: duplication
1850b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  SmallVector<uint64_t, 8> FoundFns;
1860b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
1870b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  for (unsigned i = 0; i != Header.NumLoadCommands; ++i) {
1880b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    const MachOObject::LoadCommandInfo &LCI = MachOObj->getLoadCommandInfo(i);
1890b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    if (LCI.Command.Type == macho::LCT_Segment) {
1900b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer      InMemoryStruct<macho::SegmentLoadCommand> SegmentLC;
1910b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer      MachOObj->ReadSegmentLoadCommand(LCI, SegmentLC);
1920b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
1930b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer      for (unsigned SectNum = 0; SectNum != SegmentLC->NumSections; ++SectNum) {
1940b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        InMemoryStruct<macho::Section> Sect;
1950b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        MachOObj->ReadSection(LCI, SectNum, Sect);
1960b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
1970b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        Section S;
1980b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        memcpy(S.Name, Sect->Name, 16);
1990b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        S.Address = Sect->Address;
2000b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        S.Size = Sect->Size;
2010b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        S.Offset = Sect->Offset;
2020b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        S.NumRelocs = Sect->NumRelocationTableEntries;
2030b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        S.RelocTableOffset = Sect->RelocationTableOffset;
2040b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        Sections.push_back(S);
2050b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
2060b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        for (unsigned i = 0; i != SymtabLC->NumSymbolTableEntries; ++i) {
2070b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          InMemoryStruct<macho::SymbolTableEntry> STE;
2080b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          MachOObj->ReadSymbolTableEntry(SymtabLC->SymbolTableOffset, i, STE);
2090b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
2100b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          Symbol S;
2110b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          S.StringIndex = STE->StringIndex;
2120b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          S.SectionIndex = STE->SectionIndex;
2130b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          S.Value = STE->Value;
2140b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          Symbols.push_back(S);
2150b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          UnsortedSymbols.push_back(Symbols.back());
2160b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        }
2170b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer      }
2180b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    } else if (LCI.Command.Type == macho::LCT_Segment64) {
2190b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer      InMemoryStruct<macho::Segment64LoadCommand> Segment64LC;
2200b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer      MachOObj->ReadSegment64LoadCommand(LCI, Segment64LC);
2210b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
2220b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer      for (unsigned SectNum = 0; SectNum != Segment64LC->NumSections; ++SectNum) {
2230b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        InMemoryStruct<macho::Section64> Sect64;
2240b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        MachOObj->ReadSection64(LCI, SectNum, Sect64);
2250b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
2260b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        Section S;
2270b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        memcpy(S.Name, Sect64->Name, 16);
2280b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        S.Address = Sect64->Address;
2290b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        S.Size = Sect64->Size;
2300b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        S.Offset = Sect64->Offset;
2310b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        S.NumRelocs = Sect64->NumRelocationTableEntries;
2320b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        S.RelocTableOffset = Sect64->RelocationTableOffset;
2330b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        Sections.push_back(S);
2340b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
2350b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        for (unsigned i = 0; i != SymtabLC->NumSymbolTableEntries; ++i) {
2360b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          InMemoryStruct<macho::Symbol64TableEntry> STE;
2370b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          MachOObj->ReadSymbol64TableEntry(SymtabLC->SymbolTableOffset, i, STE);
2380b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
2390b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          Symbol S;
2400b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          S.StringIndex = STE->StringIndex;
2410b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          S.SectionIndex = STE->SectionIndex;
2420b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          S.Value = STE->Value;
2430b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          Symbols.push_back(S);
2440b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          UnsortedSymbols.push_back(Symbols.back());
2450b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        }
2460b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer      }
2470b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    } else if (LCI.Command.Type == macho::LCT_FunctionStarts) {
2480b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer      InMemoryStruct<macho::LinkeditDataLoadCommand> LLC;
2490b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer      MachOObj->ReadLinkeditDataLoadCommand(LCI, LLC);
2500b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
2510b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer      MachOObj->ReadULEB128s(LLC->DataOffset, FoundFns);
2520b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    }
2530b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  }
2540b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
2550b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  std::map<uint64_t, MCFunction*> FunctionMap;
2560b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
2570b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  // Sort the symbols by address, just in case they didn't come in that way.
2580b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  array_pod_sort(Symbols.begin(), Symbols.end());
2590b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
2600b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#ifndef NDEBUG
2610b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  raw_ostream &DebugOut = DebugFlag ? dbgs() : nulls();
2620b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#else
2630b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  raw_ostream &DebugOut = nulls();
2640b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#endif
2650b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
2660b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  SmallVector<MCFunction, 16> Functions;
2670b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
2680b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  for (unsigned SectIdx = 0; SectIdx != Sections.size(); SectIdx++) {
2690b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    if (strcmp(Sections[SectIdx].Name, "__text"))
2700b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer      continue;
2710b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
2720b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    uint64_t VMAddr = Sections[SectIdx].Address - Sections[SectIdx].Offset;
2730b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    for (unsigned i = 0, e = FoundFns.size(); i != e; ++i)
2740b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer      FunctionMap.insert(std::pair<uint64_t,MCFunction*>(FoundFns[i]+VMAddr,0));
2750b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
2760b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    StringRef Bytes = MachOObj->getData(Sections[SectIdx].Offset,
2770b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer                                        Sections[SectIdx].Size);
2780b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    StringRefMemoryObject memoryObject(Bytes);
2790b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    bool symbolTableWorked = false;
2800b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
2810b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    std::vector<std::pair<uint64_t, uint32_t> > Relocs;
2820b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    for (unsigned j = 0; j != Sections[SectIdx].NumRelocs; ++j) {
2830b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer      InMemoryStruct<macho::RelocationEntry> RE;
2840b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer      MachOObj->ReadRelocationEntry(Sections[SectIdx].RelocTableOffset, j, RE);
2850b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer      Relocs.push_back(std::make_pair(RE->Word0, RE->Word1 & 0xffffff));
2860b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    }
2870b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    array_pod_sort(Relocs.begin(), Relocs.end());
2880b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
2890b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    for (unsigned SymIdx = 0; SymIdx != Symbols.size(); SymIdx++) {
2900b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer      if ((unsigned)Symbols[SymIdx].SectionIndex - 1 != SectIdx)
2910b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        continue;
2920b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
2930b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer      uint64_t Start = Symbols[SymIdx].Value - Sections[SectIdx].Address;
2940b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer      uint64_t End = (SymIdx+1 == Symbols.size() ||
2950b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          Symbols[SymIdx].SectionIndex != Symbols[SymIdx+1].SectionIndex) ?
2960b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          Sections[SectIdx].Size :
2970b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          Symbols[SymIdx+1].Value - Sections[SectIdx].Address;
2980b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer      uint64_t Size;
2990b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
3000b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer      if (Start >= End)
3010b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        continue;
3020b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
3030b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer      symbolTableWorked = true;
3040b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
3050b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer      if (!CFG) {
3060b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        outs() << MachOObj->getStringAtIndex(Symbols[SymIdx].StringIndex)
3070b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          << ":\n";
3080b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        for (uint64_t Index = Start; Index < End; Index += Size) {
3090b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          MCInst Inst;
3100b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
3110b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          if (DisAsm->getInstruction(Inst, Size, memoryObject, Index,
3120b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer                                     DebugOut, nulls())) {
3130b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer            outs() << format("%8llx:\t", Sections[SectIdx].Address + Index);
3140b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer            DumpBytes(StringRef(Bytes.data() + Index, Size));
3150b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer            IP->printInst(&Inst, outs(), "");
3160b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer            outs() << "\n";
3170b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          } else {
3180b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer            errs() << "llvm-objdump: warning: invalid instruction encoding\n";
3190b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer            if (Size == 0)
3200b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer              Size = 1; // skip illegible bytes
3210b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          }
3220b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        }
3230b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer      } else {
3240b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        // Create CFG and use it for disassembly.
3250b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        SmallVector<uint64_t, 16> Calls;
3260b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        MCFunction f =
3270b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          MCFunction::createFunctionFromMC(
3280b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer              MachOObj->getStringAtIndex(Symbols[SymIdx].StringIndex),
3290b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer              DisAsm.get(),
3300b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer              memoryObject, Start, End,
3310b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer              InstrAnalysis.get(), DebugOut,
3320b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer              Calls);
3330b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
3340b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        Functions.push_back(f);
3350b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        FunctionMap[Start] = &Functions.back();
3360b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
3370b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        for (unsigned i = 0, e = Calls.size(); i != e; ++i)
3380b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          FunctionMap.insert(std::pair<uint64_t, MCFunction*>(Calls[i], 0));
3390b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer      }
3400b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    }
3410b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
3420b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    if (CFG) {
3430b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer      if (!symbolTableWorked) {
3440b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        // Create CFG and use it for disassembly.
3450b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        SmallVector<uint64_t, 16> Calls;
3460b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        MCFunction f =
3470b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          MCFunction::createFunctionFromMC("__TEXT", DisAsm.get(),
3480b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer              memoryObject, 0, Sections[SectIdx].Size,
3490b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer              InstrAnalysis.get(), DebugOut,
3500b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer              Calls);
3510b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
3520b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        Functions.push_back(f);
3530b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        FunctionMap[Sections[SectIdx].Offset] = &Functions.back();
3540b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
3550b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        for (unsigned i = 0, e = Calls.size(); i != e; ++i)
3560b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          FunctionMap.insert(std::pair<uint64_t, MCFunction*>(Calls[i], 0));
3570b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer      }
3580b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer      for (std::map<uint64_t, MCFunction*>::iterator mi = FunctionMap.begin(),
3590b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer           me = FunctionMap.end(); mi != me; ++mi)
3600b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        if (mi->second == 0) {
3610b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          SmallVector<uint64_t, 16> Calls;
3620b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          MCFunction f =
3630b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer            MCFunction::createFunctionFromMC("unknown", DisAsm.get(),
3640b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer                                             memoryObject, mi->first,
3650b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer                                             Sections[SectIdx].Size,
3660b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer                                             InstrAnalysis.get(), DebugOut,
3670b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer                                             Calls);
3680b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          Functions.push_back(f);
3690b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          mi->second = &Functions.back();
3700b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          for (unsigned i = 0, e = Calls.size(); i != e; ++i)
3710b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer            if (FunctionMap.insert(std::pair<uint64_t, MCFunction*>(Calls[i],0))
3720b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer                                                                        .second)
3730b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer              mi = FunctionMap.begin();
3740b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        }
3750b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
3760b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer      DenseSet<uint64_t> PrintedBlocks;
3770b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer      for (unsigned ffi = 0, ffe = Functions.size(); ffi != ffe; ++ffi) {
3780b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        MCFunction &f = Functions[ffi];
3790b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        for (MCFunction::iterator fi = f.begin(), fe = f.end(); fi != fe; ++fi){
3800b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          if (!PrintedBlocks.insert(fi->first).second)
3810b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer            continue;
3820b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          bool hasPreds = FunctionMap.find(fi->first) != FunctionMap.end();
3830b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
3840b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          // Only print blocks that have predecessors.
3850b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          // FIXME: Slow.
3860b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          for (MCFunction::iterator pi = f.begin(), pe = f.end(); pi != pe;
3870b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer              ++pi)
3880b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer            if (pi->second.contains(fi->first)) {
3890b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer              hasPreds = true;
3900b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer              break;
3910b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer            }
3920b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
3930b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          // Data block.
3940b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          if (!hasPreds && fi != f.begin()) {
3950b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer            uint64_t End = llvm::next(fi) == fe ? Sections[SectIdx].Size :
3960b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer                                                  llvm::next(fi)->first;
3970b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer            outs() << "# " << End-fi->first << " bytes of data:\n";
3980b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer            for (unsigned pos = fi->first; pos != End; ++pos) {
3990b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer              outs() << format("%8x:\t", Sections[SectIdx].Address + pos);
4000b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer              DumpBytes(StringRef(Bytes.data() + pos, 1));
4010b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer              outs() << format("\t.byte 0x%02x\n", (uint8_t)Bytes[pos]);
4020b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer            }
4030b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer            continue;
4040b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          }
4050b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
4060b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          if (fi->second.contains(fi->first))
4070b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer            outs() << "# Loop begin:\n";
4080b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
4090b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          for (unsigned ii = 0, ie = fi->second.getInsts().size(); ii != ie;
4100b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer               ++ii) {
4110b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer            const MCDecodedInst &Inst = fi->second.getInsts()[ii];
4120b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer            if (FunctionMap.find(Sections[SectIdx].Address + Inst.Address) !=
4130b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer                FunctionMap.end())
4140b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer              outs() << FunctionMap[Sections[SectIdx].Address + Inst.Address]->
4150b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer                                                             getName() << ":\n";
4160b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer            outs() << format("%8llx:\t", Sections[SectIdx].Address +
4170b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer                                         Inst.Address);
4180b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer            DumpBytes(StringRef(Bytes.data() + Inst.Address, Inst.Size));
4190b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer            // Simple loops.
4200b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer            if (fi->second.contains(fi->first))
4210b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer              outs() << '\t';
4220b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer            IP->printInst(&Inst.Inst, outs(), "");
4230b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer            for (unsigned j = 0; j != Relocs.size(); ++j)
4240b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer              if (Relocs[j].first >= Sections[SectIdx].Address + Inst.Address &&
4250b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer                  Relocs[j].first < Sections[SectIdx].Address + Inst.Address +
4260b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer                                    Inst.Size) {
4270b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer                outs() << "\t# "
4280b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer                   << MachOObj->getStringAtIndex(
4290b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer                                  UnsortedSymbols[Relocs[j].second].StringIndex)
4300b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer                   << ' ';
4310b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer                DumpAddress(UnsortedSymbols[Relocs[j].second].Value, Sections,
4320b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer                            MachOObj.get(), outs());
4330b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer              }
4340b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer            uint64_t targ = InstrAnalysis->evaluateBranch(Inst.Inst,
4350b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer                                                          Inst.Address,
4360b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer                                                          Inst.Size);
4370b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer            if (targ != -1ULL)
4380b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer              DumpAddress(targ, Sections, MachOObj.get(), outs());
4390b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
4400b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer            outs() << '\n';
4410b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          }
4420b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        }
4430b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
4440b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        // Start a new dot file.
4450b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        std::string Error;
4460b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        raw_fd_ostream Out((f.getName().str() + ".dot").c_str(), Error);
4470b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        if (!Error.empty()) {
4480b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          errs() << "llvm-objdump: warning: " << Error << '\n';
4490b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          continue;
4500b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        }
4510b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
4520b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        Out << "digraph " << f.getName() << " {\n";
4530b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        Out << "graph [ rankdir = \"LR\" ];\n";
4540b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        for (MCFunction::iterator i = f.begin(), e = f.end(); i != e; ++i) {
4550b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          bool hasPreds = false;
4560b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          // Only print blocks that have predecessors.
4570b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          // FIXME: Slow.
4580b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          for (MCFunction::iterator pi = f.begin(), pe = f.end(); pi != pe;
4590b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer               ++pi)
4600b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer            if (pi->second.contains(i->first)) {
4610b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer              hasPreds = true;
4620b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer              break;
4630b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer            }
4640b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
4650b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          if (!hasPreds && i != f.begin())
4660b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer            continue;
4670b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
4680b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          Out << '"' << i->first << "\" [ label=\"<a>";
4690b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          // Print instructions.
4700b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          for (unsigned ii = 0, ie = i->second.getInsts().size(); ii != ie;
4710b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer               ++ii) {
4720b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer            // Escape special chars and print the instruction in mnemonic form.
4730b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer            std::string Str;
4740b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer            raw_string_ostream OS(Str);
4750b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer            IP->printInst(&i->second.getInsts()[ii].Inst, OS, "");
4760b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer            Out << DOT::EscapeString(OS.str()) << '|';
4770b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          }
4780b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          Out << "<o>\" shape=\"record\" ];\n";
4790b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer
4800b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          // Add edges.
4810b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer          for (MCBasicBlock::succ_iterator si = i->second.succ_begin(),
4820b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer              se = i->second.succ_end(); si != se; ++si)
4830b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer            Out << i->first << ":o -> " << *si <<":a\n";
4840b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        }
4850b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer        Out << "}\n";
4860b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer      }
4870b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer    }
4880b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer  }
4890b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer}
490