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