MachODump.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631
  1. //===-- MachODump.cpp - Object file dumping utility for llvm --------------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // This file implements the MachO-specific dumper for llvm-objdump.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #include "llvm-objdump.h"
  14. #include "MCFunction.h"
  15. #include "llvm/Support/MachO.h"
  16. #include "llvm/Object/MachO.h"
  17. #include "llvm/ADT/OwningPtr.h"
  18. #include "llvm/ADT/Triple.h"
  19. #include "llvm/ADT/STLExtras.h"
  20. #include "llvm/DebugInfo/DIContext.h"
  21. #include "llvm/MC/MCAsmInfo.h"
  22. #include "llvm/MC/MCDisassembler.h"
  23. #include "llvm/MC/MCInst.h"
  24. #include "llvm/MC/MCInstPrinter.h"
  25. #include "llvm/MC/MCInstrAnalysis.h"
  26. #include "llvm/MC/MCInstrDesc.h"
  27. #include "llvm/MC/MCInstrInfo.h"
  28. #include "llvm/MC/MCSubtargetInfo.h"
  29. #include "llvm/Support/CommandLine.h"
  30. #include "llvm/Support/Debug.h"
  31. #include "llvm/Support/Format.h"
  32. #include "llvm/Support/GraphWriter.h"
  33. #include "llvm/Support/MemoryBuffer.h"
  34. #include "llvm/Support/TargetRegistry.h"
  35. #include "llvm/Support/TargetSelect.h"
  36. #include "llvm/Support/raw_ostream.h"
  37. #include "llvm/Support/system_error.h"
  38. #include <algorithm>
  39. #include <cstring>
  40. using namespace llvm;
  41. using namespace object;
  42. static cl::opt<bool>
  43. CFG("cfg", cl::desc("Create a CFG for every symbol in the object file and"
  44. "write it to a graphviz file (MachO-only)"));
  45. static cl::opt<bool>
  46. UseDbg("g", cl::desc("Print line information from debug info if available"));
  47. static cl::opt<std::string>
  48. DSYMFile("dsym", cl::desc("Use .dSYM file for debug info"));
  49. static const Target *GetTarget(const MachOObject *MachOObj) {
  50. // Figure out the target triple.
  51. llvm::Triple TT("unknown-unknown-unknown");
  52. switch (MachOObj->getHeader().CPUType) {
  53. case llvm::MachO::CPUTypeI386:
  54. TT.setArch(Triple::ArchType(Triple::x86));
  55. break;
  56. case llvm::MachO::CPUTypeX86_64:
  57. TT.setArch(Triple::ArchType(Triple::x86_64));
  58. break;
  59. case llvm::MachO::CPUTypeARM:
  60. TT.setArch(Triple::ArchType(Triple::arm));
  61. break;
  62. case llvm::MachO::CPUTypePowerPC:
  63. TT.setArch(Triple::ArchType(Triple::ppc));
  64. break;
  65. case llvm::MachO::CPUTypePowerPC64:
  66. TT.setArch(Triple::ArchType(Triple::ppc64));
  67. break;
  68. }
  69. TripleName = TT.str();
  70. // Get the target specific parser.
  71. std::string Error;
  72. const Target *TheTarget = TargetRegistry::lookupTarget(TripleName, Error);
  73. if (TheTarget)
  74. return TheTarget;
  75. errs() << "llvm-objdump: error: unable to get target for '" << TripleName
  76. << "', see --version and --triple.\n";
  77. return 0;
  78. }
  79. struct SymbolSorter {
  80. bool operator()(const SymbolRef &A, const SymbolRef &B) {
  81. SymbolRef::Type AType, BType;
  82. A.getType(AType);
  83. B.getType(BType);
  84. uint64_t AAddr, BAddr;
  85. if (AType != SymbolRef::ST_Function)
  86. AAddr = 0;
  87. else
  88. A.getAddress(AAddr);
  89. if (BType != SymbolRef::ST_Function)
  90. BAddr = 0;
  91. else
  92. B.getAddress(BAddr);
  93. return AAddr < BAddr;
  94. }
  95. };
  96. // Print additional information about an address, if available.
  97. static void DumpAddress(uint64_t Address, ArrayRef<SectionRef> Sections,
  98. MachOObject *MachOObj, raw_ostream &OS) {
  99. for (unsigned i = 0; i != Sections.size(); ++i) {
  100. uint64_t SectAddr = 0, SectSize = 0;
  101. Sections[i].getAddress(SectAddr);
  102. Sections[i].getSize(SectSize);
  103. uint64_t addr = SectAddr;
  104. if (SectAddr <= Address &&
  105. SectAddr + SectSize > Address) {
  106. StringRef bytes, name;
  107. Sections[i].getContents(bytes);
  108. Sections[i].getName(name);
  109. // Print constant strings.
  110. if (!name.compare("__cstring"))
  111. OS << '"' << bytes.substr(addr, bytes.find('\0', addr)) << '"';
  112. // Print constant CFStrings.
  113. if (!name.compare("__cfstring"))
  114. OS << "@\"" << bytes.substr(addr, bytes.find('\0', addr)) << '"';
  115. }
  116. }
  117. }
  118. typedef std::map<uint64_t, MCFunction*> FunctionMapTy;
  119. typedef SmallVector<MCFunction, 16> FunctionListTy;
  120. static void createMCFunctionAndSaveCalls(StringRef Name,
  121. const MCDisassembler *DisAsm,
  122. MemoryObject &Object, uint64_t Start,
  123. uint64_t End,
  124. MCInstrAnalysis *InstrAnalysis,
  125. uint64_t Address,
  126. raw_ostream &DebugOut,
  127. FunctionMapTy &FunctionMap,
  128. FunctionListTy &Functions) {
  129. SmallVector<uint64_t, 16> Calls;
  130. MCFunction f =
  131. MCFunction::createFunctionFromMC(Name, DisAsm, Object, Start, End,
  132. InstrAnalysis, DebugOut, Calls);
  133. Functions.push_back(f);
  134. FunctionMap[Address] = &Functions.back();
  135. // Add the gathered callees to the map.
  136. for (unsigned i = 0, e = Calls.size(); i != e; ++i)
  137. FunctionMap.insert(std::make_pair(Calls[i], (MCFunction*)0));
  138. }
  139. // Write a graphviz file for the CFG inside an MCFunction.
  140. static void emitDOTFile(const char *FileName, const MCFunction &f,
  141. MCInstPrinter *IP) {
  142. // Start a new dot file.
  143. std::string Error;
  144. raw_fd_ostream Out(FileName, Error);
  145. if (!Error.empty()) {
  146. errs() << "llvm-objdump: warning: " << Error << '\n';
  147. return;
  148. }
  149. Out << "digraph " << f.getName() << " {\n";
  150. Out << "graph [ rankdir = \"LR\" ];\n";
  151. for (MCFunction::iterator i = f.begin(), e = f.end(); i != e; ++i) {
  152. bool hasPreds = false;
  153. // Only print blocks that have predecessors.
  154. // FIXME: Slow.
  155. for (MCFunction::iterator pi = f.begin(), pe = f.end(); pi != pe;
  156. ++pi)
  157. if (pi->second.contains(i->first)) {
  158. hasPreds = true;
  159. break;
  160. }
  161. if (!hasPreds && i != f.begin())
  162. continue;
  163. Out << '"' << i->first << "\" [ label=\"<a>";
  164. // Print instructions.
  165. for (unsigned ii = 0, ie = i->second.getInsts().size(); ii != ie;
  166. ++ii) {
  167. // Escape special chars and print the instruction in mnemonic form.
  168. std::string Str;
  169. raw_string_ostream OS(Str);
  170. IP->printInst(&i->second.getInsts()[ii].Inst, OS, "");
  171. Out << DOT::EscapeString(OS.str()) << '|';
  172. }
  173. Out << "<o>\" shape=\"record\" ];\n";
  174. // Add edges.
  175. for (MCBasicBlock::succ_iterator si = i->second.succ_begin(),
  176. se = i->second.succ_end(); si != se; ++si)
  177. Out << i->first << ":o -> " << *si <<":a\n";
  178. }
  179. Out << "}\n";
  180. }
  181. static void getSectionsAndSymbols(const macho::Header &Header,
  182. MachOObjectFile *MachOObj,
  183. InMemoryStruct<macho::SymtabLoadCommand> *SymtabLC,
  184. std::vector<SectionRef> &Sections,
  185. std::vector<SymbolRef> &Symbols,
  186. SmallVectorImpl<uint64_t> &FoundFns) {
  187. error_code ec;
  188. for (symbol_iterator SI = MachOObj->begin_symbols(),
  189. SE = MachOObj->end_symbols(); SI != SE; SI.increment(ec))
  190. Symbols.push_back(*SI);
  191. for (section_iterator SI = MachOObj->begin_sections(),
  192. SE = MachOObj->end_sections(); SI != SE; SI.increment(ec)) {
  193. SectionRef SR = *SI;
  194. StringRef SectName;
  195. SR.getName(SectName);
  196. Sections.push_back(*SI);
  197. }
  198. for (unsigned i = 0; i != Header.NumLoadCommands; ++i) {
  199. const MachOObject::LoadCommandInfo &LCI =
  200. MachOObj->getObject()->getLoadCommandInfo(i);
  201. if (LCI.Command.Type == macho::LCT_FunctionStarts) {
  202. // We found a function starts segment, parse the addresses for later
  203. // consumption.
  204. InMemoryStruct<macho::LinkeditDataLoadCommand> LLC;
  205. MachOObj->getObject()->ReadLinkeditDataLoadCommand(LCI, LLC);
  206. MachOObj->getObject()->ReadULEB128s(LLC->DataOffset, FoundFns);
  207. }
  208. }
  209. }
  210. void llvm::DisassembleInputMachO(StringRef Filename) {
  211. OwningPtr<MemoryBuffer> Buff;
  212. if (error_code ec = MemoryBuffer::getFileOrSTDIN(Filename, Buff)) {
  213. errs() << "llvm-objdump: " << Filename << ": " << ec.message() << "\n";
  214. return;
  215. }
  216. OwningPtr<MachOObjectFile> MachOOF(static_cast<MachOObjectFile*>(
  217. ObjectFile::createMachOObjectFile(Buff.take())));
  218. MachOObject *MachOObj = MachOOF->getObject();
  219. const Target *TheTarget = GetTarget(MachOObj);
  220. if (!TheTarget) {
  221. // GetTarget prints out stuff.
  222. return;
  223. }
  224. OwningPtr<const MCInstrInfo> InstrInfo(TheTarget->createMCInstrInfo());
  225. OwningPtr<MCInstrAnalysis>
  226. InstrAnalysis(TheTarget->createMCInstrAnalysis(InstrInfo.get()));
  227. // Set up disassembler.
  228. OwningPtr<const MCAsmInfo> AsmInfo(TheTarget->createMCAsmInfo(TripleName));
  229. OwningPtr<const MCSubtargetInfo>
  230. STI(TheTarget->createMCSubtargetInfo(TripleName, "", ""));
  231. OwningPtr<const MCDisassembler> DisAsm(TheTarget->createMCDisassembler(*STI));
  232. int AsmPrinterVariant = AsmInfo->getAssemblerDialect();
  233. OwningPtr<MCInstPrinter> IP(TheTarget->createMCInstPrinter(
  234. AsmPrinterVariant, *AsmInfo, *STI));
  235. if (!InstrAnalysis || !AsmInfo || !STI || !DisAsm || !IP) {
  236. errs() << "error: couldn't initialize disassembler for target "
  237. << TripleName << '\n';
  238. return;
  239. }
  240. outs() << '\n' << Filename << ":\n\n";
  241. const macho::Header &Header = MachOObj->getHeader();
  242. const MachOObject::LoadCommandInfo *SymtabLCI = 0;
  243. // First, find the symbol table segment.
  244. for (unsigned i = 0; i != Header.NumLoadCommands; ++i) {
  245. const MachOObject::LoadCommandInfo &LCI = MachOObj->getLoadCommandInfo(i);
  246. if (LCI.Command.Type == macho::LCT_Symtab) {
  247. SymtabLCI = &LCI;
  248. break;
  249. }
  250. }
  251. // Read and register the symbol table data.
  252. InMemoryStruct<macho::SymtabLoadCommand> SymtabLC;
  253. MachOObj->ReadSymtabLoadCommand(*SymtabLCI, SymtabLC);
  254. MachOObj->RegisterStringTable(*SymtabLC);
  255. std::vector<SectionRef> Sections;
  256. std::vector<SymbolRef> Symbols;
  257. SmallVector<uint64_t, 8> FoundFns;
  258. getSectionsAndSymbols(Header, MachOOF.get(), &SymtabLC, Sections, Symbols,
  259. FoundFns);
  260. // Make a copy of the unsorted symbol list. FIXME: duplication
  261. std::vector<SymbolRef> UnsortedSymbols(Symbols);
  262. // Sort the symbols by address, just in case they didn't come in that way.
  263. std::sort(Symbols.begin(), Symbols.end(), SymbolSorter());
  264. #ifndef NDEBUG
  265. raw_ostream &DebugOut = DebugFlag ? dbgs() : nulls();
  266. #else
  267. raw_ostream &DebugOut = nulls();
  268. #endif
  269. StringRef DebugAbbrevSection, DebugInfoSection, DebugArangesSection,
  270. DebugLineSection, DebugStrSection;
  271. OwningPtr<DIContext> diContext;
  272. OwningPtr<MachOObjectFile> DSYMObj;
  273. MachOObject *DbgInfoObj = MachOObj;
  274. // Try to find debug info and set up the DIContext for it.
  275. if (UseDbg) {
  276. ArrayRef<SectionRef> DebugSections = Sections;
  277. std::vector<SectionRef> DSYMSections;
  278. // A separate DSym file path was specified, parse it as a macho file,
  279. // get the sections and supply it to the section name parsing machinery.
  280. if (!DSYMFile.empty()) {
  281. OwningPtr<MemoryBuffer> Buf;
  282. if (error_code ec = MemoryBuffer::getFileOrSTDIN(DSYMFile.c_str(), Buf)) {
  283. errs() << "llvm-objdump: " << Filename << ": " << ec.message() << '\n';
  284. return;
  285. }
  286. DSYMObj.reset(static_cast<MachOObjectFile*>(
  287. ObjectFile::createMachOObjectFile(Buf.take())));
  288. const macho::Header &Header = DSYMObj->getObject()->getHeader();
  289. std::vector<SymbolRef> Symbols;
  290. SmallVector<uint64_t, 8> FoundFns;
  291. getSectionsAndSymbols(Header, DSYMObj.get(), 0, DSYMSections, Symbols,
  292. FoundFns);
  293. DebugSections = DSYMSections;
  294. DbgInfoObj = DSYMObj.get()->getObject();
  295. }
  296. // Find the named debug info sections.
  297. for (unsigned SectIdx = 0; SectIdx != DebugSections.size(); SectIdx++) {
  298. StringRef SectName;
  299. if (!DebugSections[SectIdx].getName(SectName)) {
  300. if (SectName.equals("__DWARF,__debug_abbrev"))
  301. DebugSections[SectIdx].getContents(DebugAbbrevSection);
  302. else if (SectName.equals("__DWARF,__debug_info"))
  303. DebugSections[SectIdx].getContents(DebugInfoSection);
  304. else if (SectName.equals("__DWARF,__debug_aranges"))
  305. DebugSections[SectIdx].getContents(DebugArangesSection);
  306. else if (SectName.equals("__DWARF,__debug_line"))
  307. DebugSections[SectIdx].getContents(DebugLineSection);
  308. else if (SectName.equals("__DWARF,__debug_str"))
  309. DebugSections[SectIdx].getContents(DebugStrSection);
  310. }
  311. }
  312. // Setup the DIContext.
  313. diContext.reset(DIContext::getDWARFContext(DbgInfoObj->isLittleEndian(),
  314. DebugInfoSection,
  315. DebugAbbrevSection,
  316. DebugArangesSection,
  317. DebugLineSection,
  318. DebugStrSection));
  319. }
  320. FunctionMapTy FunctionMap;
  321. FunctionListTy Functions;
  322. for (unsigned SectIdx = 0; SectIdx != Sections.size(); SectIdx++) {
  323. StringRef SectName;
  324. if (Sections[SectIdx].getName(SectName) ||
  325. SectName.compare("__TEXT,__text"))
  326. continue; // Skip non-text sections
  327. // Insert the functions from the function starts segment into our map.
  328. uint64_t VMAddr;
  329. Sections[SectIdx].getAddress(VMAddr);
  330. for (unsigned i = 0, e = FoundFns.size(); i != e; ++i) {
  331. StringRef SectBegin;
  332. Sections[SectIdx].getContents(SectBegin);
  333. uint64_t Offset = (uint64_t)SectBegin.data();
  334. FunctionMap.insert(std::make_pair(VMAddr + FoundFns[i]-Offset,
  335. (MCFunction*)0));
  336. }
  337. StringRef Bytes;
  338. Sections[SectIdx].getContents(Bytes);
  339. StringRefMemoryObject memoryObject(Bytes);
  340. bool symbolTableWorked = false;
  341. // Parse relocations.
  342. std::vector<std::pair<uint64_t, SymbolRef> > Relocs;
  343. error_code ec;
  344. for (relocation_iterator RI = Sections[SectIdx].begin_relocations(),
  345. RE = Sections[SectIdx].end_relocations(); RI != RE; RI.increment(ec)) {
  346. uint64_t RelocOffset, SectionAddress;
  347. RI->getAddress(RelocOffset);
  348. Sections[SectIdx].getAddress(SectionAddress);
  349. RelocOffset -= SectionAddress;
  350. SymbolRef RelocSym;
  351. RI->getSymbol(RelocSym);
  352. Relocs.push_back(std::make_pair(RelocOffset, RelocSym));
  353. }
  354. array_pod_sort(Relocs.begin(), Relocs.end());
  355. // Disassemble symbol by symbol.
  356. for (unsigned SymIdx = 0; SymIdx != Symbols.size(); SymIdx++) {
  357. StringRef SymName;
  358. Symbols[SymIdx].getName(SymName);
  359. SymbolRef::Type ST;
  360. Symbols[SymIdx].getType(ST);
  361. if (ST != SymbolRef::ST_Function)
  362. continue;
  363. // Make sure the symbol is defined in this section.
  364. bool containsSym = false;
  365. Sections[SectIdx].containsSymbol(Symbols[SymIdx], containsSym);
  366. if (!containsSym)
  367. continue;
  368. // Start at the address of the symbol relative to the section's address.
  369. uint64_t Start = 0;
  370. Symbols[SymIdx].getOffset(Start);
  371. // Stop disassembling either at the beginning of the next symbol or at
  372. // the end of the section.
  373. bool containsNextSym = true;
  374. uint64_t NextSym = 0;
  375. uint64_t NextSymIdx = SymIdx+1;
  376. while (Symbols.size() > NextSymIdx) {
  377. SymbolRef::Type NextSymType;
  378. Symbols[NextSymIdx].getType(NextSymType);
  379. if (NextSymType == SymbolRef::ST_Function) {
  380. Sections[SectIdx].containsSymbol(Symbols[NextSymIdx],
  381. containsNextSym);
  382. Symbols[NextSymIdx].getOffset(NextSym);
  383. break;
  384. }
  385. ++NextSymIdx;
  386. }
  387. uint64_t SectSize;
  388. Sections[SectIdx].getSize(SectSize);
  389. uint64_t End = containsNextSym ? NextSym : SectSize;
  390. uint64_t Size;
  391. symbolTableWorked = true;
  392. if (!CFG) {
  393. // Normal disassembly, print addresses, bytes and mnemonic form.
  394. StringRef SymName;
  395. Symbols[SymIdx].getName(SymName);
  396. outs() << SymName << ":\n";
  397. DILineInfo lastLine;
  398. for (uint64_t Index = Start; Index < End; Index += Size) {
  399. MCInst Inst;
  400. if (DisAsm->getInstruction(Inst, Size, memoryObject, Index,
  401. DebugOut, nulls())) {
  402. uint64_t SectAddress = 0;
  403. Sections[SectIdx].getAddress(SectAddress);
  404. outs() << format("%8" PRIx64 ":\t", SectAddress + Index);
  405. DumpBytes(StringRef(Bytes.data() + Index, Size));
  406. IP->printInst(&Inst, outs(), "");
  407. // Print debug info.
  408. if (diContext) {
  409. DILineInfo dli =
  410. diContext->getLineInfoForAddress(SectAddress + Index);
  411. // Print valid line info if it changed.
  412. if (dli != lastLine && dli.getLine() != 0)
  413. outs() << "\t## " << dli.getFileName() << ':'
  414. << dli.getLine() << ':' << dli.getColumn();
  415. lastLine = dli;
  416. }
  417. outs() << "\n";
  418. } else {
  419. errs() << "llvm-objdump: warning: invalid instruction encoding\n";
  420. if (Size == 0)
  421. Size = 1; // skip illegible bytes
  422. }
  423. }
  424. } else {
  425. // Create CFG and use it for disassembly.
  426. StringRef SymName;
  427. Symbols[SymIdx].getName(SymName);
  428. createMCFunctionAndSaveCalls(
  429. SymName, DisAsm.get(), memoryObject, Start, End,
  430. InstrAnalysis.get(), Start, DebugOut, FunctionMap, Functions);
  431. }
  432. }
  433. if (CFG) {
  434. if (!symbolTableWorked) {
  435. // Reading the symbol table didn't work, create a big __TEXT symbol.
  436. uint64_t SectSize = 0, SectAddress = 0;
  437. Sections[SectIdx].getSize(SectSize);
  438. Sections[SectIdx].getAddress(SectAddress);
  439. createMCFunctionAndSaveCalls("__TEXT", DisAsm.get(), memoryObject,
  440. 0, SectSize,
  441. InstrAnalysis.get(),
  442. SectAddress, DebugOut,
  443. FunctionMap, Functions);
  444. }
  445. for (std::map<uint64_t, MCFunction*>::iterator mi = FunctionMap.begin(),
  446. me = FunctionMap.end(); mi != me; ++mi)
  447. if (mi->second == 0) {
  448. // Create functions for the remaining callees we have gathered,
  449. // but we didn't find a name for them.
  450. uint64_t SectSize = 0;
  451. Sections[SectIdx].getSize(SectSize);
  452. SmallVector<uint64_t, 16> Calls;
  453. MCFunction f =
  454. MCFunction::createFunctionFromMC("unknown", DisAsm.get(),
  455. memoryObject, mi->first,
  456. SectSize,
  457. InstrAnalysis.get(), DebugOut,
  458. Calls);
  459. Functions.push_back(f);
  460. mi->second = &Functions.back();
  461. for (unsigned i = 0, e = Calls.size(); i != e; ++i) {
  462. std::pair<uint64_t, MCFunction*> p(Calls[i], (MCFunction*)0);
  463. if (FunctionMap.insert(p).second)
  464. mi = FunctionMap.begin();
  465. }
  466. }
  467. DenseSet<uint64_t> PrintedBlocks;
  468. for (unsigned ffi = 0, ffe = Functions.size(); ffi != ffe; ++ffi) {
  469. MCFunction &f = Functions[ffi];
  470. for (MCFunction::iterator fi = f.begin(), fe = f.end(); fi != fe; ++fi){
  471. if (!PrintedBlocks.insert(fi->first).second)
  472. continue; // We already printed this block.
  473. // We assume a block has predecessors when it's the first block after
  474. // a symbol.
  475. bool hasPreds = FunctionMap.find(fi->first) != FunctionMap.end();
  476. // See if this block has predecessors.
  477. // FIXME: Slow.
  478. for (MCFunction::iterator pi = f.begin(), pe = f.end(); pi != pe;
  479. ++pi)
  480. if (pi->second.contains(fi->first)) {
  481. hasPreds = true;
  482. break;
  483. }
  484. uint64_t SectSize = 0, SectAddress;
  485. Sections[SectIdx].getSize(SectSize);
  486. Sections[SectIdx].getAddress(SectAddress);
  487. // No predecessors, this is a data block. Print as .byte directives.
  488. if (!hasPreds) {
  489. uint64_t End = llvm::next(fi) == fe ? SectSize :
  490. llvm::next(fi)->first;
  491. outs() << "# " << End-fi->first << " bytes of data:\n";
  492. for (unsigned pos = fi->first; pos != End; ++pos) {
  493. outs() << format("%8x:\t", SectAddress + pos);
  494. DumpBytes(StringRef(Bytes.data() + pos, 1));
  495. outs() << format("\t.byte 0x%02x\n", (uint8_t)Bytes[pos]);
  496. }
  497. continue;
  498. }
  499. if (fi->second.contains(fi->first)) // Print a header for simple loops
  500. outs() << "# Loop begin:\n";
  501. DILineInfo lastLine;
  502. // Walk over the instructions and print them.
  503. for (unsigned ii = 0, ie = fi->second.getInsts().size(); ii != ie;
  504. ++ii) {
  505. const MCDecodedInst &Inst = fi->second.getInsts()[ii];
  506. // If there's a symbol at this address, print its name.
  507. if (FunctionMap.find(SectAddress + Inst.Address) !=
  508. FunctionMap.end())
  509. outs() << FunctionMap[SectAddress + Inst.Address]-> getName()
  510. << ":\n";
  511. outs() << format("%8" PRIx64 ":\t", SectAddress + Inst.Address);
  512. DumpBytes(StringRef(Bytes.data() + Inst.Address, Inst.Size));
  513. if (fi->second.contains(fi->first)) // Indent simple loops.
  514. outs() << '\t';
  515. IP->printInst(&Inst.Inst, outs(), "");
  516. // Look for relocations inside this instructions, if there is one
  517. // print its target and additional information if available.
  518. for (unsigned j = 0; j != Relocs.size(); ++j)
  519. if (Relocs[j].first >= SectAddress + Inst.Address &&
  520. Relocs[j].first < SectAddress + Inst.Address + Inst.Size) {
  521. StringRef SymName;
  522. uint64_t Addr;
  523. Relocs[j].second.getAddress(Addr);
  524. Relocs[j].second.getName(SymName);
  525. outs() << "\t# " << SymName << ' ';
  526. DumpAddress(Addr, Sections, MachOObj, outs());
  527. }
  528. // If this instructions contains an address, see if we can evaluate
  529. // it and print additional information.
  530. uint64_t targ = InstrAnalysis->evaluateBranch(Inst.Inst,
  531. Inst.Address,
  532. Inst.Size);
  533. if (targ != -1ULL)
  534. DumpAddress(targ, Sections, MachOObj, outs());
  535. // Print debug info.
  536. if (diContext) {
  537. DILineInfo dli =
  538. diContext->getLineInfoForAddress(SectAddress + Inst.Address);
  539. // Print valid line info if it changed.
  540. if (dli != lastLine && dli.getLine() != 0)
  541. outs() << "\t## " << dli.getFileName() << ':'
  542. << dli.getLine() << ':' << dli.getColumn();
  543. lastLine = dli;
  544. }
  545. outs() << '\n';
  546. }
  547. }
  548. emitDOTFile((f.getName().str() + ".dot").c_str(), f, IP.get());
  549. }
  550. }
  551. }
  552. }