MachODump.cpp revision ec8eac6d8b70234b2dfee623190d609e17206bca
1e0e734eea052a4e8372e6f430ef41149128ba0a6Chris Lattner//===-- MachODump.cpp - Object file dumping utility for llvm --------------===// 2fd93908ae8b9684fe71c239e3c6cfe13ff6a2663Misha Brukman// 3b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell// The LLVM Compiler Infrastructure 4b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell// 54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source 64ee451de366474b9c228b4e5fa573795a715216dChris Lattner// License. See LICENSE.TXT for details. 7fd93908ae8b9684fe71c239e3c6cfe13ff6a2663Misha Brukman// 8b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell//===----------------------------------------------------------------------===// 9e0e734eea052a4e8372e6f430ef41149128ba0a6Chris Lattner// 1092094b4d928119eceac1484331acffe950f4651cChris Lattner// This file implements the MachO-specific dumper for llvm-objdump. 1192094b4d928119eceac1484331acffe950f4651cChris Lattner// 1292094b4d928119eceac1484331acffe950f4651cChris Lattner//===----------------------------------------------------------------------===// 1392094b4d928119eceac1484331acffe950f4651cChris Lattner 14e4365b2e8c79f9b2d564f31fdcc0568da8e5d60fChris Lattner#include "llvm-objdump.h" 1592094b4d928119eceac1484331acffe950f4651cChris Lattner#include "MCFunction.h" 1692094b4d928119eceac1484331acffe950f4651cChris Lattner#include "llvm/Support/MachO.h" 172e6e741b737960ecd0b68610875050019aac0f07Chris Lattner#include "llvm/Object/MachO.h" 182741c971044d2165be572749b94398043caccfebChris Lattner#include "llvm/ADT/OwningPtr.h" 192741c971044d2165be572749b94398043caccfebChris Lattner#include "llvm/ADT/Triple.h" 202741c971044d2165be572749b94398043caccfebChris Lattner#include "llvm/ADT/STLExtras.h" 212e6e741b737960ecd0b68610875050019aac0f07Chris Lattner#include "llvm/DebugInfo/DIContext.h" 222e6e741b737960ecd0b68610875050019aac0f07Chris Lattner#include "llvm/MC/MCAsmInfo.h" 232e6e741b737960ecd0b68610875050019aac0f07Chris Lattner#include "llvm/MC/MCDisassembler.h" 242e6e741b737960ecd0b68610875050019aac0f07Chris Lattner#include "llvm/MC/MCInst.h" 252e6e741b737960ecd0b68610875050019aac0f07Chris Lattner#include "llvm/MC/MCInstPrinter.h" 262e6e741b737960ecd0b68610875050019aac0f07Chris Lattner#include "llvm/MC/MCInstrAnalysis.h" 272e6e741b737960ecd0b68610875050019aac0f07Chris Lattner#include "llvm/MC/MCInstrDesc.h" 282e6e741b737960ecd0b68610875050019aac0f07Chris Lattner#include "llvm/MC/MCInstrInfo.h" 29e488064922f12c4cf07f3aef9a4d2d3ffd15f9c0Chris Lattner#include "llvm/MC/MCSubtargetInfo.h" 30e0e734eea052a4e8372e6f430ef41149128ba0a6Chris Lattner#include "llvm/Support/CommandLine.h" 31e0e734eea052a4e8372e6f430ef41149128ba0a6Chris Lattner#include "llvm/Support/Debug.h" 32e0e734eea052a4e8372e6f430ef41149128ba0a6Chris Lattner#include "llvm/Support/Format.h" 331f309c1a4e8068a64627c612a895d9b403dbcb26Chris Lattner#include "llvm/Support/GraphWriter.h" 34e0e734eea052a4e8372e6f430ef41149128ba0a6Chris Lattner#include "llvm/Support/MemoryBuffer.h" 3579066fa6acce02c97c714a5a6e151ed8a249721cChris Lattner#include "llvm/Support/TargetRegistry.h" 362741c971044d2165be572749b94398043caccfebChris Lattner#include "llvm/Support/TargetSelect.h" 379289ae85b41eef62ae1fadb93e99d33f723fb682Torok Edwin#include "llvm/Support/raw_ostream.h" 382741c971044d2165be572749b94398043caccfebChris Lattner#include "llvm/Support/system_error.h" 39f5e84aa0887d3fcd752d4a4fa1bb0e526be49f20Chris Lattner#include <algorithm> 400252e49f6d6973b6f347c8feafc49e28af27163aChris Lattner#include <cstring> 412ac6e2354ac9961b00fa351635ed04baf7fdd234Chris Lattnerusing namespace llvm; 422ac6e2354ac9961b00fa351635ed04baf7fdd234Chris Lattnerusing namespace object; 432ac6e2354ac9961b00fa351635ed04baf7fdd234Chris Lattner 44952eaee239d6c38f5121ed68277555344c2d6bf0Chris Lattnerstatic cl::opt<bool> 4596b651c627160e1ea0f1bb86d352d697e6c1972dDevang Patel CFG("cfg", cl::desc("Create a CFG for every symbol in the object file and" 460de5cad74d8d2987b92b8d76af3f1eab988b3c7bChris Lattner "write it to a graphviz file (MachO-only)")); 47a6a36f59b42703c5da0f68e0db37605c2e1633bfChris Lattner 489133fe28954d498fc4de13064c7d65bd811de02cReid Spencerstatic cl::opt<bool> 49551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer UseDbg("g", cl::desc("Print line information from debug info if available")); 50ce63ffb52f249b62cdf2d250c128007b13f27e71Daniel Dunbar 51551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencerstatic cl::opt<std::string> 52551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer DSYMFile("dsym", cl::desc("Use .dSYM file for debug info")); 53e0e734eea052a4e8372e6f430ef41149128ba0a6Chris Lattner 5492094b4d928119eceac1484331acffe950f4651cChris Lattnerstatic const Target *GetTarget(const MachOObject *MachOObj) { 55d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke // Figure out the target triple. 560e5f499638c8d277b9dc4a4385712177c53b5681Chris Lattner llvm::Triple TT("unknown-unknown-unknown"); 570e5f499638c8d277b9dc4a4385712177c53b5681Chris Lattner switch (MachOObj->getHeader().CPUType) { 580e5f499638c8d277b9dc4a4385712177c53b5681Chris Lattner case llvm::MachO::CPUTypeI386: 590e5f499638c8d277b9dc4a4385712177c53b5681Chris Lattner TT.setArch(Triple::ArchType(Triple::x86)); 600e5f499638c8d277b9dc4a4385712177c53b5681Chris Lattner break; 610e5f499638c8d277b9dc4a4385712177c53b5681Chris Lattner case llvm::MachO::CPUTypeX86_64: 62844731a7f1909f55935e3514c9e713a62d67662eDan Gohman TT.setArch(Triple::ArchType(Triple::x86_64)); 63844731a7f1909f55935e3514c9e713a62d67662eDan Gohman break; 64844731a7f1909f55935e3514c9e713a62d67662eDan Gohman case llvm::MachO::CPUTypeARM: 652e6e741b737960ecd0b68610875050019aac0f07Chris Lattner TT.setArch(Triple::ArchType(Triple::arm)); 66844731a7f1909f55935e3514c9e713a62d67662eDan Gohman break; 673e8b6631e67e01e4960a7ba4668a50c596607473Chris Lattner case llvm::MachO::CPUTypePowerPC: 68ecd94c804a563f2a86572dcf1d2e81f397e19daaNick Lewycky TT.setArch(Triple::ArchType(Triple::ppc)); 6990c579de5a383cee278acc3f7e7b9d0a656e6a35Owen Anderson break; 70794fd75c67a2cdc128d67342c6d88a504d186896Devang Patel case llvm::MachO::CPUTypePowerPC64: 7154959d6cf68a9b575c98c074babe9867682a7271Devang Patel TT.setArch(Triple::ArchType(Triple::ppc64)); 72e0e734eea052a4e8372e6f430ef41149128ba0a6Chris Lattner break; 7394170596b715928794a55bc5a1671e3992fd2dc9Chris Lattner } 7494170596b715928794a55bc5a1671e3992fd2dc9Chris Lattner 7594170596b715928794a55bc5a1671e3992fd2dc9Chris Lattner TripleName = TT.str(); 76e0e734eea052a4e8372e6f430ef41149128ba0a6Chris Lattner 77cb2610ea037a17115ef3a01a6bdaab4e3cfdca27Chris Lattner // Get the target specific parser. 783a2b58f3adc5e9f9bffac7ce193f0570aa5a721fOwen Anderson std::string Error; 791e381fcd553a3955a10338fd305efc023d7d22e1Dan Gohman const Target *TheTarget = TargetRegistry::lookupTarget(TripleName, Error); 801e381fcd553a3955a10338fd305efc023d7d22e1Dan Gohman if (TheTarget) 81f5e84aa0887d3fcd752d4a4fa1bb0e526be49f20Chris Lattner return TheTarget; 82e418ac832c1a2813736c44f6ec5c646b4c89c339Chris Lattner 8396b651c627160e1ea0f1bb86d352d697e6c1972dDevang Patel errs() << "llvm-objdump: error: unable to get target for '" << TripleName 845c89b5240c90eb8171f999e5f06f815502d0321cDan Gohman << "', see --version and --triple.\n"; 85e0e734eea052a4e8372e6f430ef41149128ba0a6Chris Lattner return 0; 86e0e734eea052a4e8372e6f430ef41149128ba0a6Chris Lattner} 87747603e39ea3f29add9ba6c07bbefcc5c2432612Dan Gohman 884282e32712da220fd97177772e22ec1ee7e50af2Chris Lattnerstruct SymbolSorter { 8954959d6cf68a9b575c98c074babe9867682a7271Devang Patel bool operator()(const SymbolRef &A, const SymbolRef &B) { 9054959d6cf68a9b575c98c074babe9867682a7271Devang Patel SymbolRef::Type AType, BType; 9154959d6cf68a9b575c98c074babe9867682a7271Devang Patel A.getType(AType); 92e0e734eea052a4e8372e6f430ef41149128ba0a6Chris Lattner B.getType(BType); 932e6e741b737960ecd0b68610875050019aac0f07Chris Lattner 9492094b4d928119eceac1484331acffe950f4651cChris Lattner uint64_t AAddr, BAddr; 9544e2bd31f13da68bca451e4210560db3644b8208Chris Lattner if (AType != SymbolRef::ST_Function) 9692094b4d928119eceac1484331acffe950f4651cChris Lattner AAddr = 0; 974282e32712da220fd97177772e22ec1ee7e50af2Chris Lattner else 982e6e741b737960ecd0b68610875050019aac0f07Chris Lattner A.getAddress(AAddr); 992e6e741b737960ecd0b68610875050019aac0f07Chris Lattner if (BType != SymbolRef::ST_Function) 1002e6e741b737960ecd0b68610875050019aac0f07Chris Lattner BAddr = 0; 1010252e49f6d6973b6f347c8feafc49e28af27163aChris Lattner else 1024282e32712da220fd97177772e22ec1ee7e50af2Chris Lattner B.getAddress(BAddr); 103e0e734eea052a4e8372e6f430ef41149128ba0a6Chris Lattner return AAddr < BAddr; 10491d22c8b1ec2ad8f2f29804b729473ccf720fb3eDevang Patel } 10591d22c8b1ec2ad8f2f29804b729473ccf720fb3eDevang Patel}; 10691d22c8b1ec2ad8f2f29804b729473ccf720fb3eDevang Patel 10791d22c8b1ec2ad8f2f29804b729473ccf720fb3eDevang Patel// Print additional information about an address, if available. 10891d22c8b1ec2ad8f2f29804b729473ccf720fb3eDevang Patelstatic void DumpAddress(uint64_t Address, ArrayRef<SectionRef> Sections, 10991d22c8b1ec2ad8f2f29804b729473ccf720fb3eDevang Patel MachOObject *MachOObj, raw_ostream &OS) { 11091d22c8b1ec2ad8f2f29804b729473ccf720fb3eDevang Patel for (unsigned i = 0; i != Sections.size(); ++i) { 111e4365b2e8c79f9b2d564f31fdcc0568da8e5d60fChris Lattner uint64_t SectAddr = 0, SectSize = 0; 112e4365b2e8c79f9b2d564f31fdcc0568da8e5d60fChris Lattner Sections[i].getAddress(SectAddr); 1133a2b58f3adc5e9f9bffac7ce193f0570aa5a721fOwen Anderson Sections[i].getSize(SectSize); 114e4365b2e8c79f9b2d564f31fdcc0568da8e5d60fChris Lattner uint64_t addr = SectAddr; 115e4365b2e8c79f9b2d564f31fdcc0568da8e5d60fChris Lattner if (SectAddr <= Address && 116e4365b2e8c79f9b2d564f31fdcc0568da8e5d60fChris Lattner SectAddr + SectSize > Address) { 11726042420d642e810f5cdfb2da6156b74aaf80945Devang Patel StringRef bytes, name; 118e4365b2e8c79f9b2d564f31fdcc0568da8e5d60fChris Lattner Sections[i].getContents(bytes); 119952eaee239d6c38f5121ed68277555344c2d6bf0Chris Lattner Sections[i].getName(name); 120952eaee239d6c38f5121ed68277555344c2d6bf0Chris Lattner // Print constant strings. 1213a2b58f3adc5e9f9bffac7ce193f0570aa5a721fOwen Anderson if (!name.compare("__cstring")) 122cf00c4ab3ba308d45d98c5ccab87362cf802facbMisha Brukman OS << '"' << bytes.substr(addr, bytes.find('\0', addr)) << '"'; 123952eaee239d6c38f5121ed68277555344c2d6bf0Chris Lattner // Print constant CFStrings. 124952eaee239d6c38f5121ed68277555344c2d6bf0Chris Lattner if (!name.compare("__cfstring")) 12526042420d642e810f5cdfb2da6156b74aaf80945Devang Patel OS << "@\"" << bytes.substr(addr, bytes.find('\0', addr)) << '"'; 126952eaee239d6c38f5121ed68277555344c2d6bf0Chris Lattner } 127b461373fbcdc5909cc7331fa64791cd039de4bc8Chris Lattner } 128b461373fbcdc5909cc7331fa64791cd039de4bc8Chris Lattner} 12994170596b715928794a55bc5a1671e3992fd2dc9Chris Lattner 130b461373fbcdc5909cc7331fa64791cd039de4bc8Chris Lattnertypedef std::map<uint64_t, MCFunction*> FunctionMapTy; 131b461373fbcdc5909cc7331fa64791cd039de4bc8Chris Lattnertypedef SmallVector<MCFunction, 16> FunctionListTy; 132329c1c6c949d07e3fe9722ec633b4258217fd99dChris Lattnerstatic void createMCFunctionAndSaveCalls(StringRef Name, 133329c1c6c949d07e3fe9722ec633b4258217fd99dChris Lattner const MCDisassembler *DisAsm, 134b461373fbcdc5909cc7331fa64791cd039de4bc8Chris Lattner MemoryObject &Object, uint64_t Start, 135b461373fbcdc5909cc7331fa64791cd039de4bc8Chris Lattner uint64_t End, 136e0e734eea052a4e8372e6f430ef41149128ba0a6Chris Lattner MCInstrAnalysis *InstrAnalysis, 137e0e734eea052a4e8372e6f430ef41149128ba0a6Chris Lattner uint64_t Address, 138a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner raw_ostream &DebugOut, 139a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner FunctionMapTy &FunctionMap, 140a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner FunctionListTy &Functions) { 141a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner SmallVector<uint64_t, 16> Calls; 142a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner MCFunction f = 143a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner MCFunction::createFunctionFromMC(Name, DisAsm, Object, Start, End, 144a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner InstrAnalysis, DebugOut, Calls); 145a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner Functions.push_back(f); 146a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner FunctionMap[Address] = &Functions.back(); 147a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner 148a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner // Add the gathered callees to the map. 149fd93908ae8b9684fe71c239e3c6cfe13ff6a2663Misha Brukman for (unsigned i = 0, e = Calls.size(); i != e; ++i) 15026042420d642e810f5cdfb2da6156b74aaf80945Devang Patel FunctionMap.insert(std::make_pair(Calls[i], (MCFunction*)0)); 15126042420d642e810f5cdfb2da6156b74aaf80945Devang Patel} 152fd93908ae8b9684fe71c239e3c6cfe13ff6a2663Misha Brukman 153a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner// Write a graphviz file for the CFG inside an MCFunction. 1542741c971044d2165be572749b94398043caccfebChris Lattnerstatic void emitDOTFile(const char *FileName, const MCFunction &f, 1553472ae1e7b0f38c4ac0802ffc2900f71a5470c3bEric Christopher MCInstPrinter *IP) { 1563472ae1e7b0f38c4ac0802ffc2900f71a5470c3bEric Christopher // Start a new dot file. 1573472ae1e7b0f38c4ac0802ffc2900f71a5470c3bEric Christopher std::string Error; 158a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner raw_fd_ostream Out(FileName, Error); 159a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner if (!Error.empty()) { 1603a2b58f3adc5e9f9bffac7ce193f0570aa5a721fOwen Anderson errs() << "llvm-objdump: warning: " << Error << '\n'; 161a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner return; 162fd93908ae8b9684fe71c239e3c6cfe13ff6a2663Misha Brukman } 1633472ae1e7b0f38c4ac0802ffc2900f71a5470c3bEric Christopher 1643472ae1e7b0f38c4ac0802ffc2900f71a5470c3bEric Christopher Out << "digraph " << f.getName() << " {\n"; 1653472ae1e7b0f38c4ac0802ffc2900f71a5470c3bEric Christopher Out << "graph [ rankdir = \"LR\" ];\n"; 166a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner for (MCFunction::iterator i = f.begin(), e = f.end(); i != e; ++i) { 167a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner bool hasPreds = false; 168a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner // Only print blocks that have predecessors. 169a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner // FIXME: Slow. 170a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner for (MCFunction::iterator pi = f.begin(), pe = f.end(); pi != pe; 171a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner ++pi) 172a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner if (pi->second.contains(i->first)) { 173a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner hasPreds = true; 174a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner break; 175a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner } 17694170596b715928794a55bc5a1671e3992fd2dc9Chris Lattner 17794170596b715928794a55bc5a1671e3992fd2dc9Chris Lattner if (!hasPreds && i != f.begin()) 17894170596b715928794a55bc5a1671e3992fd2dc9Chris Lattner continue; 1797e70829632f82de15db187845666aaca6e04b792Chris Lattner 180e0e734eea052a4e8372e6f430ef41149128ba0a6Chris Lattner Out << '"' << i->first << "\" [ label=\"<a>"; 181a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner // Print instructions. 182a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner for (unsigned ii = 0, ie = i->second.getInsts().size(); ii != ie; 183a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner ++ii) { 1849966c03aad031f738718bed3bc00371e358beb5dTanya Lattner // Escape special chars and print the instruction in mnemonic form. 185a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner std::string Str; 1869966c03aad031f738718bed3bc00371e358beb5dTanya Lattner raw_string_ostream OS(Str); 18794170596b715928794a55bc5a1671e3992fd2dc9Chris Lattner IP->printInst(&i->second.getInsts()[ii].Inst, OS, ""); 18894170596b715928794a55bc5a1671e3992fd2dc9Chris Lattner Out << DOT::EscapeString(OS.str()) << '|'; 189fd93908ae8b9684fe71c239e3c6cfe13ff6a2663Misha Brukman } 190f3e1d6977ee5fb6b66df314d65e28e2c35d6e244Chris Lattner Out << "<o>\" shape=\"record\" ];\n"; 1910252e49f6d6973b6f347c8feafc49e28af27163aChris Lattner 192f3e1d6977ee5fb6b66df314d65e28e2c35d6e244Chris Lattner // Add edges. 1932e6e741b737960ecd0b68610875050019aac0f07Chris Lattner for (MCBasicBlock::succ_iterator si = i->second.succ_begin(), 194f5e84aa0887d3fcd752d4a4fa1bb0e526be49f20Chris Lattner se = i->second.succ_end(); si != se; ++si) 195a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner Out << i->first << ":o -> " << *si <<":a\n"; 196a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner } 197a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner Out << "}\n"; 198e0e734eea052a4e8372e6f430ef41149128ba0a6Chris Lattner} 199e488064922f12c4cf07f3aef9a4d2d3ffd15f9c0Chris Lattner 200e0e734eea052a4e8372e6f430ef41149128ba0a6Chris Lattnerstatic void getSectionsAndSymbols(const macho::Header &Header, 201e0e734eea052a4e8372e6f430ef41149128ba0a6Chris Lattner MachOObjectFile *MachOObj, 202e0e734eea052a4e8372e6f430ef41149128ba0a6Chris Lattner InMemoryStruct<macho::SymtabLoadCommand> *SymtabLC, 203844731a7f1909f55935e3514c9e713a62d67662eDan Gohman std::vector<SectionRef> &Sections, 204d13db2c59cc94162d6cf0a04187d408bfef6d4a7Owen Anderson std::vector<SymbolRef> &Symbols, 205844731a7f1909f55935e3514c9e713a62d67662eDan Gohman SmallVectorImpl<uint64_t> &FoundFns) { 206394f0441e06dafca29f0752cf400990a5b8fe4b1Daniel Dunbar error_code ec; 207e0e734eea052a4e8372e6f430ef41149128ba0a6Chris Lattner for (symbol_iterator SI = MachOObj->begin_symbols(), 2088d246f09cb46fe38aa71d2a4edcd84f30c4bf80eDevang Patel SE = MachOObj->end_symbols(); SI != SE; SI.increment(ec)) 2098d246f09cb46fe38aa71d2a4edcd84f30c4bf80eDevang Patel Symbols.push_back(*SI); 2108d246f09cb46fe38aa71d2a4edcd84f30c4bf80eDevang Patel 21194170596b715928794a55bc5a1671e3992fd2dc9Chris Lattner for (section_iterator SI = MachOObj->begin_sections(), 21254959d6cf68a9b575c98c074babe9867682a7271Devang Patel SE = MachOObj->end_sections(); SI != SE; SI.increment(ec)) { 2132e6e741b737960ecd0b68610875050019aac0f07Chris Lattner SectionRef SR = *SI; 214e0e734eea052a4e8372e6f430ef41149128ba0a6Chris Lattner StringRef SectName; 2152e6e741b737960ecd0b68610875050019aac0f07Chris Lattner SR.getName(SectName); 2162e6e741b737960ecd0b68610875050019aac0f07Chris Lattner Sections.push_back(*SI); 217f5e84aa0887d3fcd752d4a4fa1bb0e526be49f20Chris Lattner } 2183a2b58f3adc5e9f9bffac7ce193f0570aa5a721fOwen Anderson 219f5e84aa0887d3fcd752d4a4fa1bb0e526be49f20Chris Lattner for (unsigned i = 0; i != Header.NumLoadCommands; ++i) { 22054959d6cf68a9b575c98c074babe9867682a7271Devang Patel const MachOObject::LoadCommandInfo &LCI = 2214282e32712da220fd97177772e22ec1ee7e50af2Chris Lattner MachOObj->getObject()->getLoadCommandInfo(i); 22254959d6cf68a9b575c98c074babe9867682a7271Devang Patel if (LCI.Command.Type == macho::LCT_FunctionStarts) { 22354959d6cf68a9b575c98c074babe9867682a7271Devang Patel // We found a function starts segment, parse the addresses for later 22454959d6cf68a9b575c98c074babe9867682a7271Devang Patel // consumption. 2254282e32712da220fd97177772e22ec1ee7e50af2Chris Lattner InMemoryStruct<macho::LinkeditDataLoadCommand> LLC; 2264282e32712da220fd97177772e22ec1ee7e50af2Chris Lattner MachOObj->getObject()->ReadLinkeditDataLoadCommand(LCI, LLC); 22794170596b715928794a55bc5a1671e3992fd2dc9Chris Lattner 22854959d6cf68a9b575c98c074babe9867682a7271Devang Patel MachOObj->getObject()->ReadULEB128s(LLC->DataOffset, FoundFns); 22954959d6cf68a9b575c98c074babe9867682a7271Devang Patel } 2304282e32712da220fd97177772e22ec1ee7e50af2Chris Lattner } 2314282e32712da220fd97177772e22ec1ee7e50af2Chris Lattner} 2324282e32712da220fd97177772e22ec1ee7e50af2Chris Lattner 2334282e32712da220fd97177772e22ec1ee7e50af2Chris Lattnervoid llvm::DisassembleInputMachO(StringRef Filename) { 2344282e32712da220fd97177772e22ec1ee7e50af2Chris Lattner OwningPtr<MemoryBuffer> Buff; 2352e6e741b737960ecd0b68610875050019aac0f07Chris Lattner 23654959d6cf68a9b575c98c074babe9867682a7271Devang Patel if (error_code ec = MemoryBuffer::getFileOrSTDIN(Filename, Buff)) { 237e0e734eea052a4e8372e6f430ef41149128ba0a6Chris Lattner errs() << "llvm-objdump: " << Filename << ": " << ec.message() << "\n"; 238e0e734eea052a4e8372e6f430ef41149128ba0a6Chris Lattner return; 23999a57216a935a512c418032f590a4660bad9d846Chris Lattner } 24099a57216a935a512c418032f590a4660bad9d846Chris Lattner 24199a57216a935a512c418032f590a4660bad9d846Chris Lattner OwningPtr<MachOObjectFile> MachOOF(static_cast<MachOObjectFile*>( 2422e6e741b737960ecd0b68610875050019aac0f07Chris Lattner ObjectFile::createMachOObjectFile(Buff.take()))); 2430252e49f6d6973b6f347c8feafc49e28af27163aChris Lattner MachOObject *MachOObj = MachOOF->getObject(); 2442e6e741b737960ecd0b68610875050019aac0f07Chris Lattner 2452e6e741b737960ecd0b68610875050019aac0f07Chris Lattner const Target *TheTarget = GetTarget(MachOObj); 2469b78763fce4cb418e7a2e672efb84bac25559b79Dan Gohman if (!TheTarget) { 2479b78763fce4cb418e7a2e672efb84bac25559b79Dan Gohman // GetTarget prints out stuff. 2489b78763fce4cb418e7a2e672efb84bac25559b79Dan Gohman return; 2494282e32712da220fd97177772e22ec1ee7e50af2Chris Lattner } 2509b78763fce4cb418e7a2e672efb84bac25559b79Dan Gohman OwningPtr<const MCInstrInfo> InstrInfo(TheTarget->createMCInstrInfo()); 2519b78763fce4cb418e7a2e672efb84bac25559b79Dan Gohman OwningPtr<MCInstrAnalysis> 2522e6e741b737960ecd0b68610875050019aac0f07Chris Lattner InstrAnalysis(TheTarget->createMCInstrAnalysis(InstrInfo.get())); 253e0e734eea052a4e8372e6f430ef41149128ba0a6Chris Lattner 254e0e734eea052a4e8372e6f430ef41149128ba0a6Chris Lattner // Set up disassembler. 255e0e734eea052a4e8372e6f430ef41149128ba0a6Chris Lattner OwningPtr<const MCAsmInfo> AsmInfo(TheTarget->createMCAsmInfo(TripleName)); 256e0e734eea052a4e8372e6f430ef41149128ba0a6Chris Lattner OwningPtr<const MCSubtargetInfo> 257e0e734eea052a4e8372e6f430ef41149128ba0a6Chris Lattner STI(TheTarget->createMCSubtargetInfo(TripleName, "", "")); 258952eaee239d6c38f5121ed68277555344c2d6bf0Chris Lattner OwningPtr<const MCDisassembler> DisAsm(TheTarget->createMCDisassembler(*STI)); 259952eaee239d6c38f5121ed68277555344c2d6bf0Chris Lattner int AsmPrinterVariant = AsmInfo->getAssemblerDialect(); 260af5cbc82bb6410129425c98bbfc1ffc4c3d0f411Nick Lewycky OwningPtr<MCInstPrinter> IP(TheTarget->createMCInstPrinter( 261e4365b2e8c79f9b2d564f31fdcc0568da8e5d60fChris Lattner AsmPrinterVariant, *AsmInfo, *STI)); 262952eaee239d6c38f5121ed68277555344c2d6bf0Chris Lattner 26303e896bd6073efc4523d8bcd0239d6ed62126db7Dan Gohman if (!InstrAnalysis || !AsmInfo || !STI || !DisAsm || !IP) { 26403e896bd6073efc4523d8bcd0239d6ed62126db7Dan Gohman errs() << "error: couldn't initialize disassembler for target " 26503e896bd6073efc4523d8bcd0239d6ed62126db7Dan Gohman << TripleName << '\n'; 26603e896bd6073efc4523d8bcd0239d6ed62126db7Dan Gohman return; 267e0e734eea052a4e8372e6f430ef41149128ba0a6Chris Lattner } 2682e6e741b737960ecd0b68610875050019aac0f07Chris Lattner 269e488064922f12c4cf07f3aef9a4d2d3ffd15f9c0Chris Lattner outs() << '\n' << Filename << ":\n\n"; 270e488064922f12c4cf07f3aef9a4d2d3ffd15f9c0Chris Lattner 271e488064922f12c4cf07f3aef9a4d2d3ffd15f9c0Chris Lattner const macho::Header &Header = MachOObj->getHeader(); 272e488064922f12c4cf07f3aef9a4d2d3ffd15f9c0Chris Lattner 273e488064922f12c4cf07f3aef9a4d2d3ffd15f9c0Chris Lattner const MachOObject::LoadCommandInfo *SymtabLCI = 0; 274e488064922f12c4cf07f3aef9a4d2d3ffd15f9c0Chris Lattner // First, find the symbol table segment. 275e488064922f12c4cf07f3aef9a4d2d3ffd15f9c0Chris Lattner for (unsigned i = 0; i != Header.NumLoadCommands; ++i) { 276e488064922f12c4cf07f3aef9a4d2d3ffd15f9c0Chris Lattner const MachOObject::LoadCommandInfo &LCI = MachOObj->getLoadCommandInfo(i); 277e0e734eea052a4e8372e6f430ef41149128ba0a6Chris Lattner if (LCI.Command.Type == macho::LCT_Symtab) { 278e0e734eea052a4e8372e6f430ef41149128ba0a6Chris Lattner SymtabLCI = &LCI; 27999a57216a935a512c418032f590a4660bad9d846Chris Lattner break; 28054959d6cf68a9b575c98c074babe9867682a7271Devang Patel } 2814282e32712da220fd97177772e22ec1ee7e50af2Chris Lattner } 2824282e32712da220fd97177772e22ec1ee7e50af2Chris Lattner 2834282e32712da220fd97177772e22ec1ee7e50af2Chris Lattner // Read and register the symbol table data. 2844282e32712da220fd97177772e22ec1ee7e50af2Chris Lattner InMemoryStruct<macho::SymtabLoadCommand> SymtabLC; 2854282e32712da220fd97177772e22ec1ee7e50af2Chris Lattner MachOObj->ReadSymtabLoadCommand(*SymtabLCI, SymtabLC); 2864282e32712da220fd97177772e22ec1ee7e50af2Chris Lattner MachOObj->RegisterStringTable(*SymtabLC); 28754959d6cf68a9b575c98c074babe9867682a7271Devang Patel 288e0e734eea052a4e8372e6f430ef41149128ba0a6Chris Lattner std::vector<SectionRef> Sections; 289e0e734eea052a4e8372e6f430ef41149128ba0a6Chris Lattner std::vector<SymbolRef> Symbols; 290e4365b2e8c79f9b2d564f31fdcc0568da8e5d60fChris Lattner SmallVector<uint64_t, 8> FoundFns; 291e4365b2e8c79f9b2d564f31fdcc0568da8e5d60fChris Lattner 2923a2b58f3adc5e9f9bffac7ce193f0570aa5a721fOwen Anderson getSectionsAndSymbols(Header, MachOOF.get(), &SymtabLC, Sections, Symbols, 293e4365b2e8c79f9b2d564f31fdcc0568da8e5d60fChris Lattner FoundFns); 294e4365b2e8c79f9b2d564f31fdcc0568da8e5d60fChris Lattner 295e4365b2e8c79f9b2d564f31fdcc0568da8e5d60fChris Lattner // Make a copy of the unsorted symbol list. FIXME: duplication 29626042420d642e810f5cdfb2da6156b74aaf80945Devang Patel std::vector<SymbolRef> UnsortedSymbols(Symbols); 2973a2b58f3adc5e9f9bffac7ce193f0570aa5a721fOwen Anderson // Sort the symbols by address, just in case they didn't come in that way. 2983a2b58f3adc5e9f9bffac7ce193f0570aa5a721fOwen Anderson std::sort(Symbols.begin(), Symbols.end(), SymbolSorter()); 299e4365b2e8c79f9b2d564f31fdcc0568da8e5d60fChris Lattner 300e4365b2e8c79f9b2d564f31fdcc0568da8e5d60fChris Lattner#ifndef NDEBUG 301e4365b2e8c79f9b2d564f31fdcc0568da8e5d60fChris Lattner raw_ostream &DebugOut = DebugFlag ? dbgs() : nulls(); 302e4365b2e8c79f9b2d564f31fdcc0568da8e5d60fChris Lattner#else 3030de5cad74d8d2987b92b8d76af3f1eab988b3c7bChris Lattner raw_ostream &DebugOut = nulls(); 30426042420d642e810f5cdfb2da6156b74aaf80945Devang Patel#endif 305e4365b2e8c79f9b2d564f31fdcc0568da8e5d60fChris Lattner 306e4365b2e8c79f9b2d564f31fdcc0568da8e5d60fChris Lattner StringRef DebugAbbrevSection, DebugInfoSection, DebugArangesSection, 307e4365b2e8c79f9b2d564f31fdcc0568da8e5d60fChris Lattner DebugLineSection, DebugStrSection; 308e4365b2e8c79f9b2d564f31fdcc0568da8e5d60fChris Lattner OwningPtr<DIContext> diContext; 309e4365b2e8c79f9b2d564f31fdcc0568da8e5d60fChris Lattner OwningPtr<MachOObjectFile> DSYMObj; 310e4365b2e8c79f9b2d564f31fdcc0568da8e5d60fChris Lattner MachOObject *DbgInfoObj = MachOObj; 311e4365b2e8c79f9b2d564f31fdcc0568da8e5d60fChris Lattner // Try to find debug info and set up the DIContext for it. 312a3df8a964aa9d0d171fd4f6e491c7d1cf9dee500Chris Lattner if (UseDbg) { 313a3df8a964aa9d0d171fd4f6e491c7d1cf9dee500Chris Lattner ArrayRef<SectionRef> DebugSections = Sections; 3140de5cad74d8d2987b92b8d76af3f1eab988b3c7bChris Lattner std::vector<SectionRef> DSYMSections; 3150de5cad74d8d2987b92b8d76af3f1eab988b3c7bChris Lattner 3160de5cad74d8d2987b92b8d76af3f1eab988b3c7bChris Lattner // A separate DSym file path was specified, parse it as a macho file, 3170de5cad74d8d2987b92b8d76af3f1eab988b3c7bChris Lattner // get the sections and supply it to the section name parsing machinery. 318cb7f65342291caa3636cb50c0ee04b383cd79f8dChris Lattner if (!DSYMFile.empty()) { 3190de5cad74d8d2987b92b8d76af3f1eab988b3c7bChris Lattner OwningPtr<MemoryBuffer> Buf; 3200de5cad74d8d2987b92b8d76af3f1eab988b3c7bChris Lattner if (error_code ec = MemoryBuffer::getFileOrSTDIN(DSYMFile.c_str(), Buf)) { 3210de5cad74d8d2987b92b8d76af3f1eab988b3c7bChris Lattner errs() << "llvm-objdump: " << Filename << ": " << ec.message() << '\n'; 3220de5cad74d8d2987b92b8d76af3f1eab988b3c7bChris Lattner return; 3230de5cad74d8d2987b92b8d76af3f1eab988b3c7bChris Lattner } 3240de5cad74d8d2987b92b8d76af3f1eab988b3c7bChris Lattner DSYMObj.reset(static_cast<MachOObjectFile*>( 325fd93908ae8b9684fe71c239e3c6cfe13ff6a2663Misha Brukman ObjectFile::createMachOObjectFile(Buf.take()))); 326e4365b2e8c79f9b2d564f31fdcc0568da8e5d60fChris Lattner const macho::Header &Header = DSYMObj->getObject()->getHeader(); 327e4365b2e8c79f9b2d564f31fdcc0568da8e5d60fChris Lattner 328e4365b2e8c79f9b2d564f31fdcc0568da8e5d60fChris Lattner std::vector<SymbolRef> Symbols; 329e4365b2e8c79f9b2d564f31fdcc0568da8e5d60fChris Lattner SmallVector<uint64_t, 8> FoundFns; 330e4365b2e8c79f9b2d564f31fdcc0568da8e5d60fChris Lattner getSectionsAndSymbols(Header, DSYMObj.get(), 0, DSYMSections, Symbols, 33170ac2dcb841dc62f08e16f0b0e2cefbf01baa4c5Chris Lattner FoundFns); 332a3df8a964aa9d0d171fd4f6e491c7d1cf9dee500Chris Lattner DebugSections = DSYMSections; 333e4365b2e8c79f9b2d564f31fdcc0568da8e5d60fChris Lattner DbgInfoObj = DSYMObj.get()->getObject(); 334a3df8a964aa9d0d171fd4f6e491c7d1cf9dee500Chris Lattner } 335e4365b2e8c79f9b2d564f31fdcc0568da8e5d60fChris Lattner 336e4365b2e8c79f9b2d564f31fdcc0568da8e5d60fChris Lattner // Find the named debug info sections. 337e4365b2e8c79f9b2d564f31fdcc0568da8e5d60fChris Lattner for (unsigned SectIdx = 0; SectIdx != DebugSections.size(); SectIdx++) { 338952eaee239d6c38f5121ed68277555344c2d6bf0Chris Lattner StringRef SectName; 339952eaee239d6c38f5121ed68277555344c2d6bf0Chris Lattner if (!DebugSections[SectIdx].getName(SectName)) { 3403a2b58f3adc5e9f9bffac7ce193f0570aa5a721fOwen Anderson if (SectName.equals("__DWARF,__debug_abbrev")) 341952eaee239d6c38f5121ed68277555344c2d6bf0Chris Lattner DebugSections[SectIdx].getContents(DebugAbbrevSection); 342952eaee239d6c38f5121ed68277555344c2d6bf0Chris Lattner else if (SectName.equals("__DWARF,__debug_info")) 34326042420d642e810f5cdfb2da6156b74aaf80945Devang Patel DebugSections[SectIdx].getContents(DebugInfoSection); 3443a2b58f3adc5e9f9bffac7ce193f0570aa5a721fOwen Anderson else if (SectName.equals("__DWARF,__debug_aranges")) 3453a2b58f3adc5e9f9bffac7ce193f0570aa5a721fOwen Anderson DebugSections[SectIdx].getContents(DebugArangesSection); 346952eaee239d6c38f5121ed68277555344c2d6bf0Chris Lattner else if (SectName.equals("__DWARF,__debug_line")) 347b461373fbcdc5909cc7331fa64791cd039de4bc8Chris Lattner DebugSections[SectIdx].getContents(DebugLineSection); 348ed6dfc2856cd44a8aa608a9074eabbf42dd6cadcChris Lattner else if (SectName.equals("__DWARF,__debug_str")) 349952eaee239d6c38f5121ed68277555344c2d6bf0Chris Lattner DebugSections[SectIdx].getContents(DebugStrSection); 350a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner } 351a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner } 352ed6dfc2856cd44a8aa608a9074eabbf42dd6cadcChris Lattner 353a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner // Setup the DIContext. 354a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner diContext.reset(DIContext::getDWARFContext(DbgInfoObj->isLittleEndian(), 355fd93908ae8b9684fe71c239e3c6cfe13ff6a2663Misha Brukman DebugInfoSection, 3562ac6e2354ac9961b00fa351635ed04baf7fdd234Chris Lattner DebugAbbrevSection, 3572ac6e2354ac9961b00fa351635ed04baf7fdd234Chris Lattner DebugArangesSection, 3582ac6e2354ac9961b00fa351635ed04baf7fdd234Chris Lattner DebugLineSection, 3592ac6e2354ac9961b00fa351635ed04baf7fdd234Chris Lattner DebugStrSection)); 3602ac6e2354ac9961b00fa351635ed04baf7fdd234Chris Lattner } 3612ac6e2354ac9961b00fa351635ed04baf7fdd234Chris Lattner 3622ac6e2354ac9961b00fa351635ed04baf7fdd234Chris Lattner FunctionMapTy FunctionMap; 3632ac6e2354ac9961b00fa351635ed04baf7fdd234Chris Lattner FunctionListTy Functions; 3642ac6e2354ac9961b00fa351635ed04baf7fdd234Chris Lattner 3652ac6e2354ac9961b00fa351635ed04baf7fdd234Chris Lattner for (unsigned SectIdx = 0; SectIdx != Sections.size(); SectIdx++) { 3662ac6e2354ac9961b00fa351635ed04baf7fdd234Chris Lattner StringRef SectName; 3672ac6e2354ac9961b00fa351635ed04baf7fdd234Chris Lattner if (Sections[SectIdx].getName(SectName) || 368e4365b2e8c79f9b2d564f31fdcc0568da8e5d60fChris Lattner SectName.compare("__TEXT,__text")) 369e4365b2e8c79f9b2d564f31fdcc0568da8e5d60fChris Lattner continue; // Skip non-text sections 370e4365b2e8c79f9b2d564f31fdcc0568da8e5d60fChris Lattner 371e4365b2e8c79f9b2d564f31fdcc0568da8e5d60fChris Lattner // Insert the functions from the function starts segment into our map. 372fd93908ae8b9684fe71c239e3c6cfe13ff6a2663Misha Brukman uint64_t VMAddr; 373e4365b2e8c79f9b2d564f31fdcc0568da8e5d60fChris Lattner Sections[SectIdx].getAddress(VMAddr); 3743c80a51cfd5e7187439ce4c051da77ee46e0ff9aChris Lattner for (unsigned i = 0, e = FoundFns.size(); i != e; ++i) { 3752ac6e2354ac9961b00fa351635ed04baf7fdd234Chris Lattner StringRef SectBegin; 376952eaee239d6c38f5121ed68277555344c2d6bf0Chris Lattner Sections[SectIdx].getContents(SectBegin); 37726042420d642e810f5cdfb2da6156b74aaf80945Devang Patel uint64_t Offset = (uint64_t)SectBegin.data(); 378952eaee239d6c38f5121ed68277555344c2d6bf0Chris Lattner FunctionMap.insert(std::make_pair(VMAddr + FoundFns[i]-Offset, 37956b7ee20dad7160a117ea0d102fc5432074ce2d0Chris Lattner (MCFunction*)0)); 380952eaee239d6c38f5121ed68277555344c2d6bf0Chris Lattner } 381952eaee239d6c38f5121ed68277555344c2d6bf0Chris Lattner 382a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner StringRef Bytes; 383a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner Sections[SectIdx].getContents(Bytes); 384a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner StringRefMemoryObject memoryObject(Bytes); 385a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner bool symbolTableWorked = false; 386ed6dfc2856cd44a8aa608a9074eabbf42dd6cadcChris Lattner 387ed6dfc2856cd44a8aa608a9074eabbf42dd6cadcChris Lattner // Parse relocations. 388ed6dfc2856cd44a8aa608a9074eabbf42dd6cadcChris Lattner std::vector<std::pair<uint64_t, SymbolRef> > Relocs; 389ed6dfc2856cd44a8aa608a9074eabbf42dd6cadcChris Lattner error_code ec; 390ed6dfc2856cd44a8aa608a9074eabbf42dd6cadcChris Lattner for (relocation_iterator RI = Sections[SectIdx].begin_relocations(), 391967948b4e25cae3de68f38fddaa75d838e676decChris Lattner RE = Sections[SectIdx].end_relocations(); RI != RE; RI.increment(ec)) { 392967948b4e25cae3de68f38fddaa75d838e676decChris Lattner uint64_t RelocOffset, SectionAddress; 393dab249b3b762cff0ff16069b3233e4c885e75347Dan Gohman RI->getAddress(RelocOffset); 394967948b4e25cae3de68f38fddaa75d838e676decChris Lattner Sections[SectIdx].getAddress(SectionAddress); 395967948b4e25cae3de68f38fddaa75d838e676decChris Lattner RelocOffset -= SectionAddress; 396ed6dfc2856cd44a8aa608a9074eabbf42dd6cadcChris Lattner 397f3e1d6977ee5fb6b66df314d65e28e2c35d6e244Chris Lattner SymbolRef RelocSym; 398f3e1d6977ee5fb6b66df314d65e28e2c35d6e244Chris Lattner RI->getSymbol(RelocSym); 399fc2a3ed0c9e32cf7edaf5030fa0972b916cc5f0bDan Gohman 400f3e1d6977ee5fb6b66df314d65e28e2c35d6e244Chris Lattner Relocs.push_back(std::make_pair(RelocOffset, RelocSym)); 401118dd0ce3d8e4b0a945afc95c9538d5005abacdeChris Lattner } 402118dd0ce3d8e4b0a945afc95c9538d5005abacdeChris Lattner array_pod_sort(Relocs.begin(), Relocs.end()); 403dff6710717b159f089c76a07eda074eb6347eb92Duncan Sands 404dff6710717b159f089c76a07eda074eb6347eb92Duncan Sands // Disassemble symbol by symbol. 405dff6710717b159f089c76a07eda074eb6347eb92Duncan Sands for (unsigned SymIdx = 0; SymIdx != Symbols.size(); SymIdx++) { 406dff6710717b159f089c76a07eda074eb6347eb92Duncan Sands StringRef SymName; 407dff6710717b159f089c76a07eda074eb6347eb92Duncan Sands Symbols[SymIdx].getName(SymName); 408dff6710717b159f089c76a07eda074eb6347eb92Duncan Sands 409dff6710717b159f089c76a07eda074eb6347eb92Duncan Sands SymbolRef::Type ST; 410dff6710717b159f089c76a07eda074eb6347eb92Duncan Sands Symbols[SymIdx].getType(ST); 411dff6710717b159f089c76a07eda074eb6347eb92Duncan Sands if (ST != SymbolRef::ST_Function) 412dff6710717b159f089c76a07eda074eb6347eb92Duncan Sands continue; 413dff6710717b159f089c76a07eda074eb6347eb92Duncan Sands 414dff6710717b159f089c76a07eda074eb6347eb92Duncan Sands // Make sure the symbol is defined in this section. 415dff6710717b159f089c76a07eda074eb6347eb92Duncan Sands bool containsSym = false; 416118dd0ce3d8e4b0a945afc95c9538d5005abacdeChris Lattner Sections[SectIdx].containsSymbol(Symbols[SymIdx], containsSym); 417118dd0ce3d8e4b0a945afc95c9538d5005abacdeChris Lattner if (!containsSym) 418dff6710717b159f089c76a07eda074eb6347eb92Duncan Sands continue; 419118dd0ce3d8e4b0a945afc95c9538d5005abacdeChris Lattner 420118dd0ce3d8e4b0a945afc95c9538d5005abacdeChris Lattner // Start at the address of the symbol relative to the section's address. 421118dd0ce3d8e4b0a945afc95c9538d5005abacdeChris Lattner uint64_t SectionAddress = 0; 422118dd0ce3d8e4b0a945afc95c9538d5005abacdeChris Lattner uint64_t Start = 0; 423fd93908ae8b9684fe71c239e3c6cfe13ff6a2663Misha Brukman Sections[SectIdx].getAddress(SectionAddress); 424118dd0ce3d8e4b0a945afc95c9538d5005abacdeChris Lattner Symbols[SymIdx].getAddress(Start); 425ed6dfc2856cd44a8aa608a9074eabbf42dd6cadcChris Lattner Start -= SectionAddress; 426ed6dfc2856cd44a8aa608a9074eabbf42dd6cadcChris Lattner 4273da59db637a887474c1b1346c1f3ccf53b6c4663Reid Spencer // Stop disassembling either at the beginning of the next symbol or at 428832254e1c2387c0cbeb0a820b8315fbe85cb003aReid Spencer // the end of the section. 429d8af90c1da64b81a7aa167b5adcc1e81b0741252Dan Gohman bool containsNextSym = true; 430d8af90c1da64b81a7aa167b5adcc1e81b0741252Dan Gohman uint64_t NextSym = 0; 431d8af90c1da64b81a7aa167b5adcc1e81b0741252Dan Gohman uint64_t NextSymIdx = SymIdx+1; 432a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner while (Symbols.size() > NextSymIdx) { 433a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner SymbolRef::Type NextSymType; 434a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner Symbols[NextSymIdx].getType(NextSymType); 435a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner if (NextSymType == SymbolRef::ST_Function) { 436a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner Sections[SectIdx].containsSymbol(Symbols[NextSymIdx], 437a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner containsNextSym); 438a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner Symbols[NextSymIdx].getAddress(NextSym); 439ea9403f2aa078e840a49792d906390395f0cd2f6Chris Lattner NextSym -= SectionAddress; 440ea9403f2aa078e840a49792d906390395f0cd2f6Chris Lattner break; 441ea9403f2aa078e840a49792d906390395f0cd2f6Chris Lattner } 442ea9403f2aa078e840a49792d906390395f0cd2f6Chris Lattner ++NextSymIdx; 443ea9403f2aa078e840a49792d906390395f0cd2f6Chris Lattner } 444ea9403f2aa078e840a49792d906390395f0cd2f6Chris Lattner 445ea9403f2aa078e840a49792d906390395f0cd2f6Chris Lattner uint64_t SectSize; 446ea9403f2aa078e840a49792d906390395f0cd2f6Chris Lattner Sections[SectIdx].getSize(SectSize); 44792329c7fbe572892c17aa2d2542a10e3ea16132fDan Gohman uint64_t End = containsNextSym ? NextSym : SectSize; 448a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner uint64_t Size; 449ea9403f2aa078e840a49792d906390395f0cd2f6Chris Lattner 450ea9403f2aa078e840a49792d906390395f0cd2f6Chris Lattner symbolTableWorked = true; 451a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner 452a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner if (!CFG) { 453a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner // Normal disassembly, print addresses, bytes and mnemonic form. 454a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner StringRef SymName; 455a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner Symbols[SymIdx].getName(SymName); 456a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner 457a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner outs() << SymName << ":\n"; 458a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner DILineInfo lastLine; 459a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner for (uint64_t Index = Start; Index < End; Index += Size) { 460a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner MCInst Inst; 461a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner 4623280f7bd557250a448eb56edbddfc90c94a406e6Chris Lattner if (DisAsm->getInstruction(Inst, Size, memoryObject, Index, 463a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner DebugOut, nulls())) { 464a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner uint64_t SectAddress = 0; 465ed6dfc2856cd44a8aa608a9074eabbf42dd6cadcChris Lattner Sections[SectIdx].getAddress(SectAddress); 466ed6dfc2856cd44a8aa608a9074eabbf42dd6cadcChris Lattner outs() << format("%8" PRIx64 ":\t", SectAddress + Index); 467ed6dfc2856cd44a8aa608a9074eabbf42dd6cadcChris Lattner 468ed6dfc2856cd44a8aa608a9074eabbf42dd6cadcChris Lattner DumpBytes(StringRef(Bytes.data() + Index, Size)); 469a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner IP->printInst(&Inst, outs(), ""); 470a3df8a964aa9d0d171fd4f6e491c7d1cf9dee500Chris Lattner 471a3df8a964aa9d0d171fd4f6e491c7d1cf9dee500Chris Lattner // Print debug info. 472a3df8a964aa9d0d171fd4f6e491c7d1cf9dee500Chris Lattner if (diContext) { 473a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner DILineInfo dli = 474a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner diContext->getLineInfoForAddress(SectAddress + Index); 47539a383124b70dda1fea18288235114029ede76cfNick Lewycky // Print valid line info if it changed. 476a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner if (dli != lastLine && dli.getLine() != 0) 477b7211a2ce13a0365e0e1dd2f27adda2ee3d1288bDevang Patel outs() << "\t## " << dli.getFileName() << ':' 478d7bc19dfee3f2ce8e9c8b9193bdfb93a67008a39Chris Lattner << dli.getLine() << ':' << dli.getColumn(); 479df45bd3803ae0965a83cd1f30ee051b9f43e73ddChris Lattner lastLine = dli; 480df45bd3803ae0965a83cd1f30ee051b9f43e73ddChris Lattner } 481118dd0ce3d8e4b0a945afc95c9538d5005abacdeChris Lattner outs() << "\n"; 482df45bd3803ae0965a83cd1f30ee051b9f43e73ddChris Lattner } else { 483df45bd3803ae0965a83cd1f30ee051b9f43e73ddChris Lattner errs() << "llvm-objdump: warning: invalid instruction encoding\n"; 484df45bd3803ae0965a83cd1f30ee051b9f43e73ddChris Lattner if (Size == 0) 485a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner Size = 1; // skip illegible bytes 486a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner } 487a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner } 488a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner } else { 489a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner // Create CFG and use it for disassembly. 490a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner StringRef SymName; 4912741c971044d2165be572749b94398043caccfebChris Lattner Symbols[SymIdx].getName(SymName); 4921bf5ebc7be0d5b05e4175c7adb767b38896adef1Devang Patel createMCFunctionAndSaveCalls( 493228ebd0f4cf9207d32d61ef4b11b81736895dc09Devang Patel SymName, DisAsm.get(), memoryObject, Start, End, 494228ebd0f4cf9207d32d61ef4b11b81736895dc09Devang Patel InstrAnalysis.get(), Start, DebugOut, FunctionMap, Functions); 495a6a36f59b42703c5da0f68e0db37605c2e1633bfChris Lattner } 496228ebd0f4cf9207d32d61ef4b11b81736895dc09Devang Patel } 4973c80a51cfd5e7187439ce4c051da77ee46e0ff9aChris Lattner 498a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner if (CFG) { 499a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner if (!symbolTableWorked) { 500a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner // Reading the symbol table didn't work, create a big __TEXT symbol. 501d9a5daeb7719c83136c0dc43d6ef732402d1a1b5Chris Lattner uint64_t SectSize = 0, SectAddress = 0; 5024282e32712da220fd97177772e22ec1ee7e50af2Chris Lattner Sections[SectIdx].getSize(SectSize); 5034282e32712da220fd97177772e22ec1ee7e50af2Chris Lattner Sections[SectIdx].getAddress(SectAddress); 5044282e32712da220fd97177772e22ec1ee7e50af2Chris Lattner createMCFunctionAndSaveCalls("__TEXT", DisAsm.get(), memoryObject, 5054282e32712da220fd97177772e22ec1ee7e50af2Chris Lattner 0, SectSize, 5064282e32712da220fd97177772e22ec1ee7e50af2Chris Lattner InstrAnalysis.get(), 507a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner SectAddress, DebugOut, 508d7bc19dfee3f2ce8e9c8b9193bdfb93a67008a39Chris Lattner FunctionMap, Functions); 509d7bc19dfee3f2ce8e9c8b9193bdfb93a67008a39Chris Lattner } 510d7bc19dfee3f2ce8e9c8b9193bdfb93a67008a39Chris Lattner for (std::map<uint64_t, MCFunction*>::iterator mi = FunctionMap.begin(), 511d7bc19dfee3f2ce8e9c8b9193bdfb93a67008a39Chris Lattner me = FunctionMap.end(); mi != me; ++mi) 512a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner if (mi->second == 0) { 5132741c971044d2165be572749b94398043caccfebChris Lattner // Create functions for the remaining callees we have gathered, 5141bf5ebc7be0d5b05e4175c7adb767b38896adef1Devang Patel // but we didn't find a name for them. 515228ebd0f4cf9207d32d61ef4b11b81736895dc09Devang Patel uint64_t SectSize = 0; 516228ebd0f4cf9207d32d61ef4b11b81736895dc09Devang Patel Sections[SectIdx].getSize(SectSize); 517a6a36f59b42703c5da0f68e0db37605c2e1633bfChris Lattner 518228ebd0f4cf9207d32d61ef4b11b81736895dc09Devang Patel SmallVector<uint64_t, 16> Calls; 5193c80a51cfd5e7187439ce4c051da77ee46e0ff9aChris Lattner MCFunction f = 520d7bc19dfee3f2ce8e9c8b9193bdfb93a67008a39Chris Lattner MCFunction::createFunctionFromMC("unknown", DisAsm.get(), 521d7bc19dfee3f2ce8e9c8b9193bdfb93a67008a39Chris Lattner memoryObject, mi->first, 522d7bc19dfee3f2ce8e9c8b9193bdfb93a67008a39Chris Lattner SectSize, 523a6a36f59b42703c5da0f68e0db37605c2e1633bfChris Lattner InstrAnalysis.get(), DebugOut, 524a6a36f59b42703c5da0f68e0db37605c2e1633bfChris Lattner Calls); 525a6a36f59b42703c5da0f68e0db37605c2e1633bfChris Lattner Functions.push_back(f); 526a6a36f59b42703c5da0f68e0db37605c2e1633bfChris Lattner mi->second = &Functions.back(); 527a6a36f59b42703c5da0f68e0db37605c2e1633bfChris Lattner for (unsigned i = 0, e = Calls.size(); i != e; ++i) { 528a6a36f59b42703c5da0f68e0db37605c2e1633bfChris Lattner std::pair<uint64_t, MCFunction*> p(Calls[i], (MCFunction*)0); 529a6a36f59b42703c5da0f68e0db37605c2e1633bfChris Lattner if (FunctionMap.insert(p).second) 530d7bc19dfee3f2ce8e9c8b9193bdfb93a67008a39Chris Lattner mi = FunctionMap.begin(); 531a6a36f59b42703c5da0f68e0db37605c2e1633bfChris Lattner } 532a6a36f59b42703c5da0f68e0db37605c2e1633bfChris Lattner } 533a6a36f59b42703c5da0f68e0db37605c2e1633bfChris Lattner 534a6a36f59b42703c5da0f68e0db37605c2e1633bfChris Lattner DenseSet<uint64_t> PrintedBlocks; 535d7bc19dfee3f2ce8e9c8b9193bdfb93a67008a39Chris Lattner for (unsigned ffi = 0, ffe = Functions.size(); ffi != ffe; ++ffi) { 536a6a36f59b42703c5da0f68e0db37605c2e1633bfChris Lattner MCFunction &f = Functions[ffi]; 537d7bc19dfee3f2ce8e9c8b9193bdfb93a67008a39Chris Lattner for (MCFunction::iterator fi = f.begin(), fe = f.end(); fi != fe; ++fi){ 538d7bc19dfee3f2ce8e9c8b9193bdfb93a67008a39Chris Lattner if (!PrintedBlocks.insert(fi->first).second) 539a6a36f59b42703c5da0f68e0db37605c2e1633bfChris Lattner continue; // We already printed this block. 540d7bc19dfee3f2ce8e9c8b9193bdfb93a67008a39Chris Lattner 541d7bc19dfee3f2ce8e9c8b9193bdfb93a67008a39Chris Lattner // We assume a block has predecessors when it's the first block after 542d7bc19dfee3f2ce8e9c8b9193bdfb93a67008a39Chris Lattner // a symbol. 543a6a36f59b42703c5da0f68e0db37605c2e1633bfChris Lattner bool hasPreds = FunctionMap.find(fi->first) != FunctionMap.end(); 544d7bc19dfee3f2ce8e9c8b9193bdfb93a67008a39Chris Lattner 545a6a36f59b42703c5da0f68e0db37605c2e1633bfChris Lattner // See if this block has predecessors. 546d7bc19dfee3f2ce8e9c8b9193bdfb93a67008a39Chris Lattner // FIXME: Slow. 547d7bc19dfee3f2ce8e9c8b9193bdfb93a67008a39Chris Lattner for (MCFunction::iterator pi = f.begin(), pe = f.end(); pi != pe; 548d7bc19dfee3f2ce8e9c8b9193bdfb93a67008a39Chris Lattner ++pi) 549d7bc19dfee3f2ce8e9c8b9193bdfb93a67008a39Chris Lattner if (pi->second.contains(fi->first)) { 550a6a36f59b42703c5da0f68e0db37605c2e1633bfChris Lattner hasPreds = true; 551a6a36f59b42703c5da0f68e0db37605c2e1633bfChris Lattner break; 552d7bc19dfee3f2ce8e9c8b9193bdfb93a67008a39Chris Lattner } 553d7bc19dfee3f2ce8e9c8b9193bdfb93a67008a39Chris Lattner 554d7bc19dfee3f2ce8e9c8b9193bdfb93a67008a39Chris Lattner uint64_t SectSize = 0, SectAddress; 555d7bc19dfee3f2ce8e9c8b9193bdfb93a67008a39Chris Lattner Sections[SectIdx].getSize(SectSize); 556d7bc19dfee3f2ce8e9c8b9193bdfb93a67008a39Chris Lattner Sections[SectIdx].getAddress(SectAddress); 557d7bc19dfee3f2ce8e9c8b9193bdfb93a67008a39Chris Lattner 558a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner // No predecessors, this is a data block. Print as .byte directives. 559d7bc19dfee3f2ce8e9c8b9193bdfb93a67008a39Chris Lattner if (!hasPreds) { 560a6a36f59b42703c5da0f68e0db37605c2e1633bfChris Lattner uint64_t End = llvm::next(fi) == fe ? SectSize : 561a6a36f59b42703c5da0f68e0db37605c2e1633bfChris Lattner llvm::next(fi)->first; 562a6a36f59b42703c5da0f68e0db37605c2e1633bfChris Lattner outs() << "# " << End-fi->first << " bytes of data:\n"; 563d7bc19dfee3f2ce8e9c8b9193bdfb93a67008a39Chris Lattner for (unsigned pos = fi->first; pos != End; ++pos) { 564a6a36f59b42703c5da0f68e0db37605c2e1633bfChris Lattner outs() << format("%8x:\t", SectAddress + pos); 565d7bc19dfee3f2ce8e9c8b9193bdfb93a67008a39Chris Lattner DumpBytes(StringRef(Bytes.data() + pos, 1)); 566d7bc19dfee3f2ce8e9c8b9193bdfb93a67008a39Chris Lattner outs() << format("\t.byte 0x%02x\n", (uint8_t)Bytes[pos]); 567d7bc19dfee3f2ce8e9c8b9193bdfb93a67008a39Chris Lattner } 568a6a36f59b42703c5da0f68e0db37605c2e1633bfChris Lattner continue; 569a6a36f59b42703c5da0f68e0db37605c2e1633bfChris Lattner } 570d7bc19dfee3f2ce8e9c8b9193bdfb93a67008a39Chris Lattner 571a6a36f59b42703c5da0f68e0db37605c2e1633bfChris Lattner if (fi->second.contains(fi->first)) // Print a header for simple loops 572d7bc19dfee3f2ce8e9c8b9193bdfb93a67008a39Chris Lattner outs() << "# Loop begin:\n"; 573a6a36f59b42703c5da0f68e0db37605c2e1633bfChris Lattner 574a6a36f59b42703c5da0f68e0db37605c2e1633bfChris Lattner DILineInfo lastLine; 575a6a36f59b42703c5da0f68e0db37605c2e1633bfChris Lattner // Walk over the instructions and print them. 576a6a36f59b42703c5da0f68e0db37605c2e1633bfChris Lattner for (unsigned ii = 0, ie = fi->second.getInsts().size(); ii != ie; 577a6a36f59b42703c5da0f68e0db37605c2e1633bfChris Lattner ++ii) { 578a6a36f59b42703c5da0f68e0db37605c2e1633bfChris Lattner const MCDecodedInst &Inst = fi->second.getInsts()[ii]; 579a6a36f59b42703c5da0f68e0db37605c2e1633bfChris Lattner 580a6a36f59b42703c5da0f68e0db37605c2e1633bfChris Lattner // If there's a symbol at this address, print its name. 581a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner if (FunctionMap.find(SectAddress + Inst.Address) != 582a6a36f59b42703c5da0f68e0db37605c2e1633bfChris Lattner FunctionMap.end()) 583a6a36f59b42703c5da0f68e0db37605c2e1633bfChris Lattner outs() << FunctionMap[SectAddress + Inst.Address]-> getName() 584a6a36f59b42703c5da0f68e0db37605c2e1633bfChris Lattner << ":\n"; 585a6a36f59b42703c5da0f68e0db37605c2e1633bfChris Lattner 586a6a36f59b42703c5da0f68e0db37605c2e1633bfChris Lattner outs() << format("%8" PRIx64 ":\t", SectAddress + Inst.Address); 58798917503c702e16f35ccdec3f6b4c48e5c4759acChris Lattner DumpBytes(StringRef(Bytes.data() + Inst.Address, Inst.Size)); 58898917503c702e16f35ccdec3f6b4c48e5c4759acChris Lattner 58998917503c702e16f35ccdec3f6b4c48e5c4759acChris Lattner if (fi->second.contains(fi->first)) // Indent simple loops. 590a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner outs() << '\t'; 591952eaee239d6c38f5121ed68277555344c2d6bf0Chris Lattner 59294170596b715928794a55bc5a1671e3992fd2dc9Chris Lattner IP->printInst(&Inst.Inst, outs(), ""); 59394170596b715928794a55bc5a1671e3992fd2dc9Chris Lattner 59494170596b715928794a55bc5a1671e3992fd2dc9Chris Lattner // Look for relocations inside this instructions, if there is one 595a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner // print its target and additional information if available. 596f15826999bc560ee6f67cff5ecd71bf9cce7a7aaDavid Greene for (unsigned j = 0; j != Relocs.size(); ++j) 59767d1d1f8322bdc460158888cd233be8d1cb1d4abEvan Cheng if (Relocs[j].first >= SectAddress + Inst.Address && 598ed6dfc2856cd44a8aa608a9074eabbf42dd6cadcChris Lattner Relocs[j].first < SectAddress + Inst.Address + Inst.Size) { 599d9a5daeb7719c83136c0dc43d6ef732402d1a1b5Chris Lattner StringRef SymName; 600d9a5daeb7719c83136c0dc43d6ef732402d1a1b5Chris Lattner uint64_t Addr; 601fd93908ae8b9684fe71c239e3c6cfe13ff6a2663Misha Brukman Relocs[j].second.getAddress(Addr); 602a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner Relocs[j].second.getName(SymName); 603118dd0ce3d8e4b0a945afc95c9538d5005abacdeChris Lattner 6049646e6b6af1f924f9366a2bffc6dde102f84d231Chris Lattner outs() << "\t# " << SymName << ' '; 605e0e734eea052a4e8372e6f430ef41149128ba0a6Chris Lattner DumpAddress(Addr, Sections, MachOObj, outs()); 606e0e734eea052a4e8372e6f430ef41149128ba0a6Chris Lattner } 607e0e734eea052a4e8372e6f430ef41149128ba0a6Chris Lattner 608a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner // If this instructions contains an address, see if we can evaluate 609a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner // it and print additional information. 610a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner uint64_t targ = InstrAnalysis->evaluateBranch(Inst.Inst, 6119966c03aad031f738718bed3bc00371e358beb5dTanya Lattner Inst.Address, 612a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner Inst.Size); 61392094b4d928119eceac1484331acffe950f4651cChris Lattner if (targ != -1ULL) 6140b79a7727d68a507837e827803859424cf3d997bEli Friedman DumpAddress(targ, Sections, MachOObj, outs()); 6150b79a7727d68a507837e827803859424cf3d997bEli Friedman 616fd93908ae8b9684fe71c239e3c6cfe13ff6a2663Misha Brukman // Print debug info. 61792094b4d928119eceac1484331acffe950f4651cChris Lattner if (diContext) { 61892094b4d928119eceac1484331acffe950f4651cChris Lattner DILineInfo dli = 61992094b4d928119eceac1484331acffe950f4651cChris Lattner diContext->getLineInfoForAddress(SectAddress + Inst.Address); 62092094b4d928119eceac1484331acffe950f4651cChris Lattner // Print valid line info if it changed. 62192094b4d928119eceac1484331acffe950f4651cChris Lattner if (dli != lastLine && dli.getLine() != 0) 62292094b4d928119eceac1484331acffe950f4651cChris Lattner outs() << "\t## " << dli.getFileName() << ':' 62392094b4d928119eceac1484331acffe950f4651cChris Lattner << dli.getLine() << ':' << dli.getColumn(); 624a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner lastLine = dli; 62592094b4d928119eceac1484331acffe950f4651cChris Lattner } 62692094b4d928119eceac1484331acffe950f4651cChris Lattner 62792094b4d928119eceac1484331acffe950f4651cChris Lattner outs() << '\n'; 628b7211a2ce13a0365e0e1dd2f27adda2ee3d1288bDevang Patel } 6295fa802fe279f10f402e039bc931aa57c0e424bf5Chris Lattner } 6309966c03aad031f738718bed3bc00371e358beb5dTanya Lattner 6313a2b58f3adc5e9f9bffac7ce193f0570aa5a721fOwen Anderson emitDOTFile((f.getName().str() + ".dot").c_str(), f, IP.get()); 63292094b4d928119eceac1484331acffe950f4651cChris Lattner } 633a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner } 634a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner } 635a2706518f9cc34358cba1072f78235aa091d6d93Chris Lattner} 636fd93908ae8b9684fe71c239e3c6cfe13ff6a2663Misha Brukman