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