192e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer//===-- llvm-objdump.cpp - Object file dumping utility for llvm -----------===// 292e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer// 392e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer// The LLVM Compiler Infrastructure 492e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer// 592e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer// This file is distributed under the University of Illinois Open Source 692e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer// License. See LICENSE.TXT for details. 792e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer// 892e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer//===----------------------------------------------------------------------===// 992e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer// 1092e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer// This program is a utility that works like binutils "objdump", that is, it 1192e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer// dumps out a plethora of information about an object file depending on the 1292e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer// flags. 1392e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer// 14dd3aa9eab2b40ea1573a5482472bbb89e6f1038dMichael J. Spencer// The flags and output of this program should be near identical to those of 15dd3aa9eab2b40ea1573a5482472bbb89e6f1038dMichael J. Spencer// binutils objdump. 16dd3aa9eab2b40ea1573a5482472bbb89e6f1038dMichael J. Spencer// 1792e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer//===----------------------------------------------------------------------===// 1892e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer 190b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer#include "llvm-objdump.h" 20f010c464a11444733ec67e31aace8bcebeaf2588Chandler Carruth#include "llvm/ADT/STLExtras.h" 211e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer#include "llvm/ADT/StringExtras.h" 2292e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer#include "llvm/ADT/Triple.h" 23cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines#include "llvm/MC/MCAnalysis/MCAtom.h" 24cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines#include "llvm/MC/MCAnalysis/MCFunction.h" 25cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines#include "llvm/MC/MCAnalysis/MCModule.h" 26cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines#include "llvm/MC/MCAnalysis/MCModuleYAML.h" 2792e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer#include "llvm/MC/MCAsmInfo.h" 282c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha#include "llvm/MC/MCContext.h" 2992e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer#include "llvm/MC/MCDisassembler.h" 3092e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer#include "llvm/MC/MCInst.h" 3192e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer#include "llvm/MC/MCInstPrinter.h" 32ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha#include "llvm/MC/MCInstrAnalysis.h" 3317463b3ef1a3d39b10619254f12e806c8c43f9e7Craig Topper#include "llvm/MC/MCInstrInfo.h" 34ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha#include "llvm/MC/MCObjectDisassembler.h" 352c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha#include "llvm/MC/MCObjectFileInfo.h" 362c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha#include "llvm/MC/MCObjectSymbolizer.h" 37c6449b636f4984be88f128d0375c056ad05e7e8fJim Grosbach#include "llvm/MC/MCRegisterInfo.h" 382c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha#include "llvm/MC/MCRelocationInfo.h" 39ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha#include "llvm/MC/MCSubtargetInfo.h" 40f010c464a11444733ec67e31aace8bcebeaf2588Chandler Carruth#include "llvm/Object/Archive.h" 41f010c464a11444733ec67e31aace8bcebeaf2588Chandler Carruth#include "llvm/Object/COFF.h" 42cef81b37c77978cd4dddb4a5ad13564793ded155Rafael Espindola#include "llvm/Object/MachO.h" 43f010c464a11444733ec67e31aace8bcebeaf2588Chandler Carruth#include "llvm/Object/ObjectFile.h" 4427781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer#include "llvm/Support/Casting.h" 4592e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer#include "llvm/Support/CommandLine.h" 4692e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer#include "llvm/Support/Debug.h" 4727781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer#include "llvm/Support/FileSystem.h" 4892e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer#include "llvm/Support/Format.h" 49853b0fd623491ef7dafeed20ee15897e3b95d82cBenjamin Kramer#include "llvm/Support/GraphWriter.h" 5092e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer#include "llvm/Support/Host.h" 5192e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer#include "llvm/Support/ManagedStatic.h" 5292e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer#include "llvm/Support/MemoryBuffer.h" 5392e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer#include "llvm/Support/MemoryObject.h" 5492e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer#include "llvm/Support/PrettyStackTrace.h" 5592e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer#include "llvm/Support/Signals.h" 5692e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer#include "llvm/Support/SourceMgr.h" 573e74d6fdd248e20a280f1dff3da9a6c689c2c4c3Evan Cheng#include "llvm/Support/TargetRegistry.h" 583e74d6fdd248e20a280f1dff3da9a6c689c2c4c3Evan Cheng#include "llvm/Support/TargetSelect.h" 5992e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer#include "llvm/Support/raw_ostream.h" 6092e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer#include <algorithm> 6181bbdfda82a3e5528d979b2cc150e9c7e0fa4427Benjamin Kramer#include <cctype> 6292e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer#include <cstring> 63cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines#include <system_error> 64171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha 6592e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencerusing namespace llvm; 6692e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencerusing namespace object; 6792e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer 680b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramerstatic cl::list<std::string> 690b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin KramerInputFilenames(cl::Positional, cl::desc("<input object files>"),cl::ZeroOrMore); 7092e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer 710b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramerstatic cl::opt<bool> 720b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin KramerDisassemble("disassemble", 730b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer cl::desc("Display assembler mnemonics for the machine instructions")); 740b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramerstatic cl::alias 750b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin KramerDisassembled("d", cl::desc("Alias for --disassemble"), 760b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer cl::aliasopt(Disassemble)); 7792e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer 780b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramerstatic cl::opt<bool> 7927781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. SpencerRelocations("r", cl::desc("Display the relocation entries in the file")); 8027781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer 8127781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencerstatic cl::opt<bool> 821e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. SpencerSectionContents("s", cl::desc("Display the content of each section")); 831e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer 841e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencerstatic cl::opt<bool> 8522ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. SpencerSymbolTable("t", cl::desc("Display the symbol table")); 8622ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencer 8722ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencerstatic cl::opt<bool> 88cef81b37c77978cd4dddb4a5ad13564793ded155Rafael EspindolaMachOOpt("macho", cl::desc("Use MachO specific object file parser")); 890b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramerstatic cl::alias 90cef81b37c77978cd4dddb4a5ad13564793ded155Rafael EspindolaMachOm("m", cl::desc("Alias for --macho"), cl::aliasopt(MachOOpt)); 91685a2501b20baf688f6cc087f4b92bbafcd8028eBenjamin Kramer 920b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramercl::opt<std::string> 930b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramerllvm::TripleName("triple", cl::desc("Target triple to disassemble for, " 940b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer "see -version for available targets")); 9592e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer 960b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramercl::opt<std::string> 970b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramerllvm::ArchName("arch", cl::desc("Target arch to disassemble for, " 980b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer "see -version for available targets")); 9992e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer 100023bb15beaac3744ce3a5d1f750d6e32829c7130Nick Lewyckystatic cl::opt<bool> 101023bb15beaac3744ce3a5d1f750d6e32829c7130Nick LewyckySectionHeaders("section-headers", cl::desc("Display summaries of the headers " 102023bb15beaac3744ce3a5d1f750d6e32829c7130Nick Lewycky "for each section.")); 103023bb15beaac3744ce3a5d1f750d6e32829c7130Nick Lewyckystatic cl::alias 104023bb15beaac3744ce3a5d1f750d6e32829c7130Nick LewyckySectionHeadersShort("headers", cl::desc("Alias for --section-headers"), 105023bb15beaac3744ce3a5d1f750d6e32829c7130Nick Lewycky cl::aliasopt(SectionHeaders)); 106023bb15beaac3744ce3a5d1f750d6e32829c7130Nick Lewyckystatic cl::alias 107023bb15beaac3744ce3a5d1f750d6e32829c7130Nick LewyckySectionHeadersShorter("h", cl::desc("Alias for --section-headers"), 108023bb15beaac3744ce3a5d1f750d6e32829c7130Nick Lewycky cl::aliasopt(SectionHeaders)); 109023bb15beaac3744ce3a5d1f750d6e32829c7130Nick Lewycky 110fd6d1651551d5a08b3cf0fcafed5e91a40b8e317Jack Carterstatic cl::list<std::string> 111fd6d1651551d5a08b3cf0fcafed5e91a40b8e317Jack CarterMAttrs("mattr", 112fd6d1651551d5a08b3cf0fcafed5e91a40b8e317Jack Carter cl::CommaSeparated, 113fd6d1651551d5a08b3cf0fcafed5e91a40b8e317Jack Carter cl::desc("Target specific attributes"), 114fd6d1651551d5a08b3cf0fcafed5e91a40b8e317Jack Carter cl::value_desc("a1,+a2,-a3,...")); 115fd6d1651551d5a08b3cf0fcafed5e91a40b8e317Jack Carter 1168b9da530e3637fd4afb33f80673178dcc74397f0Eli Benderskystatic cl::opt<bool> 1178b9da530e3637fd4afb33f80673178dcc74397f0Eli BenderskyNoShowRawInsn("no-show-raw-insn", cl::desc("When disassembling instructions, " 1188b9da530e3637fd4afb33f80673178dcc74397f0Eli Bendersky "do not print the instruction bytes.")); 1198b9da530e3637fd4afb33f80673178dcc74397f0Eli Bendersky 120eef7b6219ebe5d0ded0be4adb3003055fa8a63c4Michael J. Spencerstatic cl::opt<bool> 121eef7b6219ebe5d0ded0be4adb3003055fa8a63c4Michael J. SpencerUnwindInfo("unwind-info", cl::desc("Display unwind information")); 122eef7b6219ebe5d0ded0be4adb3003055fa8a63c4Michael J. Spencer 123eef7b6219ebe5d0ded0be4adb3003055fa8a63c4Michael J. Spencerstatic cl::alias 124eef7b6219ebe5d0ded0be4adb3003055fa8a63c4Michael J. SpencerUnwindInfoShort("u", cl::desc("Alias for --unwind-info"), 125eef7b6219ebe5d0ded0be4adb3003055fa8a63c4Michael J. Spencer cl::aliasopt(UnwindInfo)); 126eef7b6219ebe5d0ded0be4adb3003055fa8a63c4Michael J. Spencer 127b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencerstatic cl::opt<bool> 128b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. SpencerPrivateHeaders("private-headers", 129b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer cl::desc("Display format specific file headers")); 130b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer 131b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencerstatic cl::alias 132b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. SpencerPrivateHeadersShort("p", cl::desc("Alias for --private-headers"), 133b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer cl::aliasopt(PrivateHeaders)); 134b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer 1352c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougachastatic cl::opt<bool> 1362c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed BougachaSymbolize("symbolize", cl::desc("When disassembling instructions, " 1372c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha "try to symbolize operands.")); 1382c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha 139ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougachastatic cl::opt<bool> 140ef99356dfebb96f6f90efb912c2877214bad060eAhmed BougachaCFG("cfg", cl::desc("Create a CFG for every function found in the object" 141ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha " and write it to a graphviz file")); 142ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha 143171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha// FIXME: Does it make sense to have a dedicated tool for yaml cfg output? 144171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougachastatic cl::opt<std::string> 145171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed BougachaYAMLCFG("yaml-cfg", 146171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha cl::desc("Create a CFG and write it as a YAML MCModule."), 147171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha cl::value_desc("yaml output file")); 148171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha 1490b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramerstatic StringRef ToolName; 15025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer 151cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesbool llvm::error(std::error_code EC) { 15236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!EC) 15336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return false; 15425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer 15536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines outs() << ToolName << ": error reading file: " << EC.message() << ".\n"; 1560b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer outs().flush(); 1570b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer return true; 15892e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer} 15992e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer 160dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic const Target *getTarget(const ObjectFile *Obj = nullptr) { 16192e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer // Figure out the target triple. 1629ed9e5d0f994c7721185eba963ea9b907dabcde6Kevin Enderby llvm::Triple TheTriple("unknown-unknown-unknown"); 163d11699d3c057129d0716fa548c67d1f62837f6b6Michael J. Spencer if (TripleName.empty()) { 1642c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha if (Obj) { 1659ed9e5d0f994c7721185eba963ea9b907dabcde6Kevin Enderby TheTriple.setArch(Triple::ArchType(Obj->getArch())); 1662c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha // TheTriple defaults to ELF, and COFF doesn't have an environment: 1672c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha // the best we can do here is indicate that it is mach-o. 1682c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha if (Obj->isMachO()) 16936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines TheTriple.setObjectFormat(Triple::MachO); 170dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 171dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (Obj->isCOFF()) { 172dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const auto COFFObj = dyn_cast<COFFObjectFile>(Obj); 173dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (COFFObj->getArch() == Triple::thumb) 174dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines TheTriple.setTriple("thumbv7-windows"); 175dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 1762c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha } 177d11699d3c057129d0716fa548c67d1f62837f6b6Michael J. Spencer } else 1789ed9e5d0f994c7721185eba963ea9b907dabcde6Kevin Enderby TheTriple.setTriple(Triple::normalize(TripleName)); 17992e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer 18092e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer // Get the target specific parser. 18192e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer std::string Error; 1829ed9e5d0f994c7721185eba963ea9b907dabcde6Kevin Enderby const Target *TheTarget = TargetRegistry::lookupTarget(ArchName, TheTriple, 1839ed9e5d0f994c7721185eba963ea9b907dabcde6Kevin Enderby Error); 1849ed9e5d0f994c7721185eba963ea9b907dabcde6Kevin Enderby if (!TheTarget) { 1859ed9e5d0f994c7721185eba963ea9b907dabcde6Kevin Enderby errs() << ToolName << ": " << Error; 186dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return nullptr; 1879ed9e5d0f994c7721185eba963ea9b907dabcde6Kevin Enderby } 1889ed9e5d0f994c7721185eba963ea9b907dabcde6Kevin Enderby 1899ed9e5d0f994c7721185eba963ea9b907dabcde6Kevin Enderby // Update the triple name and return the found target. 1909ed9e5d0f994c7721185eba963ea9b907dabcde6Kevin Enderby TripleName = TheTriple.getTriple(); 1919ed9e5d0f994c7721185eba963ea9b907dabcde6Kevin Enderby return TheTarget; 19292e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer} 19392e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer 194ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha// Write a graphviz file for the CFG inside an MCFunction. 195171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha// FIXME: Use GraphWriter 196ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougachastatic void emitDOTFile(const char *FileName, const MCFunction &f, 197ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha MCInstPrinter *IP) { 198ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha // Start a new dot file. 199ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha std::string Error; 20036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines raw_fd_ostream Out(FileName, Error, sys::fs::F_Text); 201ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha if (!Error.empty()) { 202ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha errs() << "llvm-objdump: warning: " << Error << '\n'; 203ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha return; 204ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha } 205ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha 206ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha Out << "digraph \"" << f.getName() << "\" {\n"; 207ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha Out << "graph [ rankdir = \"LR\" ];\n"; 208ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha for (MCFunction::const_iterator i = f.begin(), e = f.end(); i != e; ++i) { 209ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha // Only print blocks that have predecessors. 210ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha bool hasPreds = (*i)->pred_begin() != (*i)->pred_end(); 211ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha 212ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha if (!hasPreds && i != f.begin()) 213ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha continue; 214ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha 215ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha Out << '"' << (*i)->getInsts()->getBeginAddr() << "\" [ label=\"<a>"; 216ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha // Print instructions. 217ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha for (unsigned ii = 0, ie = (*i)->getInsts()->size(); ii != ie; 218ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha ++ii) { 219ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha if (ii != 0) // Not the first line, start a new row. 220ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha Out << '|'; 221ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha if (ii + 1 == ie) // Last line, add an end id. 222ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha Out << "<o>"; 223ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha 224ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha // Escape special chars and print the instruction in mnemonic form. 225ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha std::string Str; 226ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha raw_string_ostream OS(Str); 227ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha IP->printInst(&(*i)->getInsts()->at(ii).Inst, OS, ""); 228ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha Out << DOT::EscapeString(OS.str()); 229ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha } 230ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha Out << "\" shape=\"record\" ];\n"; 231ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha 232ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha // Add edges. 233ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha for (MCBasicBlock::succ_const_iterator si = (*i)->succ_begin(), 234ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha se = (*i)->succ_end(); si != se; ++si) 235ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha Out << (*i)->getInsts()->getBeginAddr() << ":o -> " 236ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha << (*si)->getInsts()->getBeginAddr() << ":a\n"; 237ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha } 238ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha Out << "}\n"; 239ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha} 2402d24e2a396a1d211baaeedf32148a3b657240170David Blaikie 2410b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramervoid llvm::DumpBytes(StringRef bytes) { 2420b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer static const char hex_rep[] = "0123456789abcdef"; 24392e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer // FIXME: The real way to do this is to figure out the longest instruction 24492e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer // and align to that size before printing. I'll fix this when I get 24592e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer // around to outputting relocations. 24692e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer // 15 is the longest x86 instruction 24792e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer // 3 is for the hex rep of a byte + a space. 24892e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer // 1 is for the null terminator. 24992e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer enum { OutputSize = (15 * 3) + 1 }; 25092e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer char output[OutputSize]; 25192e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer 25292e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer assert(bytes.size() <= 15 25392e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer && "DumpBytes only supports instructions of up to 15 bytes"); 25492e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer memset(output, ' ', sizeof(output)); 25592e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer unsigned index = 0; 25692e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer for (StringRef::iterator i = bytes.begin(), 25792e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer e = bytes.end(); i != e; ++i) { 25892e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer output[index] = hex_rep[(*i & 0xF0) >> 4]; 25992e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer output[index + 1] = hex_rep[*i & 0xF]; 26092e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer index += 3; 26192e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer } 26292e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer 26392e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer output[sizeof(output) - 1] = 0; 26492e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer outs() << output; 26592e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer} 26692e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer 267eef7b6219ebe5d0ded0be4adb3003055fa8a63c4Michael J. Spencerbool llvm::RelocAddressLess(RelocationRef a, RelocationRef b) { 268942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer uint64_t a_addr, b_addr; 269956ca7265c697107708468b7e1b2fd21f4185baeRafael Espindola if (error(a.getOffset(a_addr))) return false; 270956ca7265c697107708468b7e1b2fd21f4185baeRafael Espindola if (error(b.getOffset(b_addr))) return false; 271942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer return a_addr < b_addr; 272942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer} 273942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer 274942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencerstatic void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) { 2753f5d1a2396915ebff20ce4f5d668ee5c839d1d91Jim Grosbach const Target *TheTarget = getTarget(Obj); 2763f5d1a2396915ebff20ce4f5d668ee5c839d1d91Jim Grosbach // getTarget() will have already issued a diagnostic if necessary, so 2773f5d1a2396915ebff20ce4f5d668ee5c839d1d91Jim Grosbach // just bail here if it failed. 2783f5d1a2396915ebff20ce4f5d668ee5c839d1d91Jim Grosbach if (!TheTarget) 27992e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer return; 28092e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer 281fd6d1651551d5a08b3cf0fcafed5e91a40b8e317Jack Carter // Package up features to be passed to target/subtarget 282fd6d1651551d5a08b3cf0fcafed5e91a40b8e317Jack Carter std::string FeaturesStr; 283fd6d1651551d5a08b3cf0fcafed5e91a40b8e317Jack Carter if (MAttrs.size()) { 284fd6d1651551d5a08b3cf0fcafed5e91a40b8e317Jack Carter SubtargetFeatures Features; 285fd6d1651551d5a08b3cf0fcafed5e91a40b8e317Jack Carter for (unsigned i = 0; i != MAttrs.size(); ++i) 286fd6d1651551d5a08b3cf0fcafed5e91a40b8e317Jack Carter Features.AddFeature(MAttrs[i]); 287fd6d1651551d5a08b3cf0fcafed5e91a40b8e317Jack Carter FeaturesStr = Features.getString(); 288fd6d1651551d5a08b3cf0fcafed5e91a40b8e317Jack Carter } 289fd6d1651551d5a08b3cf0fcafed5e91a40b8e317Jack Carter 29036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<const MCRegisterInfo> MRI( 29136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines TheTarget->createMCRegInfo(TripleName)); 29227a33ad5ce3a6ca9a5d7546b41d96e975b1e9305Ahmed Bougacha if (!MRI) { 29327a33ad5ce3a6ca9a5d7546b41d96e975b1e9305Ahmed Bougacha errs() << "error: no register info for target " << TripleName << "\n"; 29427a33ad5ce3a6ca9a5d7546b41d96e975b1e9305Ahmed Bougacha return; 29527a33ad5ce3a6ca9a5d7546b41d96e975b1e9305Ahmed Bougacha } 29627a33ad5ce3a6ca9a5d7546b41d96e975b1e9305Ahmed Bougacha 29727a33ad5ce3a6ca9a5d7546b41d96e975b1e9305Ahmed Bougacha // Set up disassembler. 29836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<const MCAsmInfo> AsmInfo( 29936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines TheTarget->createMCAsmInfo(*MRI, TripleName)); 30027a33ad5ce3a6ca9a5d7546b41d96e975b1e9305Ahmed Bougacha if (!AsmInfo) { 30127a33ad5ce3a6ca9a5d7546b41d96e975b1e9305Ahmed Bougacha errs() << "error: no assembly info for target " << TripleName << "\n"; 30227a33ad5ce3a6ca9a5d7546b41d96e975b1e9305Ahmed Bougacha return; 30327a33ad5ce3a6ca9a5d7546b41d96e975b1e9305Ahmed Bougacha } 30427a33ad5ce3a6ca9a5d7546b41d96e975b1e9305Ahmed Bougacha 30536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<const MCSubtargetInfo> STI( 30636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines TheTarget->createMCSubtargetInfo(TripleName, "", FeaturesStr)); 30727a33ad5ce3a6ca9a5d7546b41d96e975b1e9305Ahmed Bougacha if (!STI) { 30827a33ad5ce3a6ca9a5d7546b41d96e975b1e9305Ahmed Bougacha errs() << "error: no subtarget info for target " << TripleName << "\n"; 30927a33ad5ce3a6ca9a5d7546b41d96e975b1e9305Ahmed Bougacha return; 31027a33ad5ce3a6ca9a5d7546b41d96e975b1e9305Ahmed Bougacha } 31127a33ad5ce3a6ca9a5d7546b41d96e975b1e9305Ahmed Bougacha 31236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<const MCInstrInfo> MII(TheTarget->createMCInstrInfo()); 3132c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha if (!MII) { 3142c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha errs() << "error: no instruction info for target " << TripleName << "\n"; 3152c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha return; 3162c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha } 3172c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha 318dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines std::unique_ptr<const MCObjectFileInfo> MOFI(new MCObjectFileInfo); 319dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MCContext Ctx(AsmInfo.get(), MRI.get(), MOFI.get()); 320dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 321dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines std::unique_ptr<MCDisassembler> DisAsm( 322dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines TheTarget->createMCDisassembler(*STI, Ctx)); 323dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 32427a33ad5ce3a6ca9a5d7546b41d96e975b1e9305Ahmed Bougacha if (!DisAsm) { 32527a33ad5ce3a6ca9a5d7546b41d96e975b1e9305Ahmed Bougacha errs() << "error: no disassembler for target " << TripleName << "\n"; 32627a33ad5ce3a6ca9a5d7546b41d96e975b1e9305Ahmed Bougacha return; 32727a33ad5ce3a6ca9a5d7546b41d96e975b1e9305Ahmed Bougacha } 32827a33ad5ce3a6ca9a5d7546b41d96e975b1e9305Ahmed Bougacha 3292c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha 3302c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha if (Symbolize) { 33136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<MCRelocationInfo> RelInfo( 332dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines TheTarget->createMCRelocationInfo(TripleName, Ctx)); 3332c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha if (RelInfo) { 33436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<MCSymbolizer> Symzer( 335dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MCObjectSymbolizer::createObjectSymbolizer(Ctx, std::move(RelInfo), 336dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Obj)); 3372c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha if (Symzer) 33836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DisAsm->setSymbolizer(std::move(Symzer)); 3392c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha } 34027a33ad5ce3a6ca9a5d7546b41d96e975b1e9305Ahmed Bougacha } 34127a33ad5ce3a6ca9a5d7546b41d96e975b1e9305Ahmed Bougacha 34236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<const MCInstrAnalysis> MIA( 34336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines TheTarget->createMCInstrAnalysis(MII.get())); 344ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha 34527a33ad5ce3a6ca9a5d7546b41d96e975b1e9305Ahmed Bougacha int AsmPrinterVariant = AsmInfo->getAssemblerDialect(); 34636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<MCInstPrinter> IP(TheTarget->createMCInstPrinter( 34727a33ad5ce3a6ca9a5d7546b41d96e975b1e9305Ahmed Bougacha AsmPrinterVariant, *AsmInfo, *MII, *MRI, *STI)); 34827a33ad5ce3a6ca9a5d7546b41d96e975b1e9305Ahmed Bougacha if (!IP) { 34927a33ad5ce3a6ca9a5d7546b41d96e975b1e9305Ahmed Bougacha errs() << "error: no instruction printer for target " << TripleName 35027a33ad5ce3a6ca9a5d7546b41d96e975b1e9305Ahmed Bougacha << '\n'; 35127a33ad5ce3a6ca9a5d7546b41d96e975b1e9305Ahmed Bougacha return; 35227a33ad5ce3a6ca9a5d7546b41d96e975b1e9305Ahmed Bougacha } 35327a33ad5ce3a6ca9a5d7546b41d96e975b1e9305Ahmed Bougacha 354171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha if (CFG || !YAMLCFG.empty()) { 35536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<MCObjectDisassembler> OD( 35636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines new MCObjectDisassembler(*Obj, *DisAsm, *MIA)); 35736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<MCModule> Mod(OD->buildModule(/* withCFG */ true)); 358ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha for (MCModule::const_atom_iterator AI = Mod->atom_begin(), 359ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha AE = Mod->atom_end(); 360ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha AI != AE; ++AI) { 361ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha outs() << "Atom " << (*AI)->getName() << ": \n"; 362ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha if (const MCTextAtom *TA = dyn_cast<MCTextAtom>(*AI)) { 363ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha for (MCTextAtom::const_iterator II = TA->begin(), IE = TA->end(); 364ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha II != IE; 365ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha ++II) { 366ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha IP->printInst(&II->Inst, outs(), ""); 367ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha outs() << "\n"; 368ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha } 369ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha } 370ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha } 371171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha if (CFG) { 372171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha for (MCModule::const_func_iterator FI = Mod->func_begin(), 373171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha FE = Mod->func_end(); 374171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha FI != FE; ++FI) { 375171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha static int filenum = 0; 376171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha emitDOTFile((Twine((*FI)->getName()) + "_" + 377171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha utostr(filenum) + ".dot").str().c_str(), 378171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha **FI, IP.get()); 379171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha ++filenum; 380171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha } 381171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha } 382171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha if (!YAMLCFG.empty()) { 383171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha std::string Error; 38436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines raw_fd_ostream YAMLOut(YAMLCFG.c_str(), Error, sys::fs::F_Text); 385171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha if (!Error.empty()) { 3867413b54c897c9a7bd04e7b918128d0279be9a126Ahmed Bougacha errs() << ToolName << ": warning: " << Error << '\n'; 387171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha return; 388171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha } 389171ac8ca175bec5bc0bff8b3006850f70e0569c9Ahmed Bougacha mcmodule2yaml(YAMLOut, *Mod, *MII, *MRI); 390ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha } 391ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha } 392ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha 39336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines StringRef Fmt = Obj->getBytesInAddress() > 4 ? "\t\t%016" PRIx64 ": " : 39436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines "\t\t\t%08" PRIx64 ": "; 39536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 39636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Create a mapping, RelocSecs = SectionRelocMap[S], where sections 39736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // in RelocSecs contain the relocations for section S. 398cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::error_code EC; 39936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::map<SectionRef, SmallVector<SectionRef, 1>> SectionRelocMap; 40036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (const SectionRef &Section : Obj->sections()) { 40136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines section_iterator Sec2 = Section.getRelocatedSection(); 40236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Sec2 != Obj->section_end()) 40336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SectionRelocMap[*Sec2].push_back(Section); 40436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 405ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha 40636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (const SectionRef &Section : Obj->sections()) { 40736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool Text; 40836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error(Section.isText(Text))) 40936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 41036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!Text) 41136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines continue; 41225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer 413942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer uint64_t SectionAddr; 41436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error(Section.getAddress(SectionAddr))) 41536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 41636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 41736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t SectSize; 41836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error(Section.getSize(SectSize))) 41936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 420942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer 421739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer // Make a list of all the symbols in this section. 42236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::vector<std::pair<uint64_t, StringRef>> Symbols; 42336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (const SymbolRef &Symbol : Obj->symbols()) { 424739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer bool contains; 42536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!error(Section.containsSymbol(Symbol, contains)) && contains) { 426739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer uint64_t Address; 42736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error(Symbol.getAddress(Address))) 42836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 42936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Address == UnknownAddressOrSize) 43036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines continue; 431aab219110994cc4d848fae5f50166a2f70ccc812Cameron Zwarich Address -= SectionAddr; 43236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Address >= SectSize) 43336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines continue; 434aab219110994cc4d848fae5f50166a2f70ccc812Cameron Zwarich 435739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer StringRef Name; 43636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error(Symbol.getName(Name))) 43736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 438739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer Symbols.push_back(std::make_pair(Address, Name)); 439739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer } 440739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer } 441739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer 442739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer // Sort the symbols by address, just in case they didn't come in that way. 443739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer array_pod_sort(Symbols.begin(), Symbols.end()); 444739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer 445942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer // Make a list of all the relocations for this section. 446942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer std::vector<RelocationRef> Rels; 447942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer if (InlineRelocs) { 44836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (const SectionRef &RelocSec : SectionRelocMap[Section]) { 44936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (const RelocationRef &Reloc : RelocSec.relocations()) { 45036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Rels.push_back(Reloc); 45136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 452942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer } 453942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer } 454942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer 455942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer // Sort relocations by address. 456942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer std::sort(Rels.begin(), Rels.end(), RelocAddressLess); 457942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer 458cef81b37c77978cd4dddb4a5ad13564793ded155Rafael Espindola StringRef SegmentName = ""; 45936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (const MachOObjectFile *MachO = dyn_cast<const MachOObjectFile>(Obj)) { 46036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DataRefImpl DR = Section.getRawDataRefImpl(); 461fd7aa38e304a09fa0ef51b85b773b649b7e58c5eRafael Espindola SegmentName = MachO->getSectionFinalSegmentName(DR); 462cef81b37c77978cd4dddb4a5ad13564793ded155Rafael Espindola } 46325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer StringRef name; 46436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error(Section.getName(name))) 46536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 466cef81b37c77978cd4dddb4a5ad13564793ded155Rafael Espindola outs() << "Disassembly of section "; 467cef81b37c77978cd4dddb4a5ad13564793ded155Rafael Espindola if (!SegmentName.empty()) 468cef81b37c77978cd4dddb4a5ad13564793ded155Rafael Espindola outs() << SegmentName << ","; 469cef81b37c77978cd4dddb4a5ad13564793ded155Rafael Espindola outs() << name << ':'; 470739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer 471739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer // If the section has no symbols just insert a dummy one and disassemble 472739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer // the whole section. 473739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer if (Symbols.empty()) 474739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer Symbols.push_back(std::make_pair(0, name)); 47592e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer 4762c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha 4772c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha SmallString<40> Comments; 4782c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha raw_svector_ostream CommentStream(Comments); 4792c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha 48025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer StringRef Bytes; 48136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error(Section.getContents(Bytes))) 48236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 4832c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha StringRefMemoryObject memoryObject(Bytes, SectionAddr); 48492e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer uint64_t Size; 48592e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer uint64_t Index; 486739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer 487942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer std::vector<RelocationRef>::const_iterator rel_cur = Rels.begin(); 488942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer std::vector<RelocationRef>::const_iterator rel_end = Rels.end(); 489739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer // Disassemble symbol by symbol. 490739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer for (unsigned si = 0, se = Symbols.size(); si != se; ++si) { 491739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer uint64_t Start = Symbols[si].first; 492178dbd44187e23e7e3f3ba17b00c89c819070296Michael J. Spencer uint64_t End; 493178dbd44187e23e7e3f3ba17b00c89c819070296Michael J. Spencer // The end is either the size of the section or the beginning of the next 494178dbd44187e23e7e3f3ba17b00c89c819070296Michael J. Spencer // symbol. 495178dbd44187e23e7e3f3ba17b00c89c819070296Michael J. Spencer if (si == se - 1) 496178dbd44187e23e7e3f3ba17b00c89c819070296Michael J. Spencer End = SectSize; 497178dbd44187e23e7e3f3ba17b00c89c819070296Michael J. Spencer // Make sure this symbol takes up space. 498178dbd44187e23e7e3f3ba17b00c89c819070296Michael J. Spencer else if (Symbols[si + 1].first != Start) 499178dbd44187e23e7e3f3ba17b00c89c819070296Michael J. Spencer End = Symbols[si + 1].first - 1; 500178dbd44187e23e7e3f3ba17b00c89c819070296Michael J. Spencer else 501178dbd44187e23e7e3f3ba17b00c89c819070296Michael J. Spencer // This symbol has the same address as the next symbol. Skip it. 502178dbd44187e23e7e3f3ba17b00c89c819070296Michael J. Spencer continue; 503178dbd44187e23e7e3f3ba17b00c89c819070296Michael J. Spencer 504739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer outs() << '\n' << Symbols[si].second << ":\n"; 505739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer 506739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer#ifndef NDEBUG 50736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines raw_ostream &DebugOut = DebugFlag ? dbgs() : nulls(); 508739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer#else 50936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines raw_ostream &DebugOut = nulls(); 510739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer#endif 511739b65bf85cf7221b8a615e83dee11ec729e2649Benjamin Kramer 5120b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer for (Index = Start; Index < End; Index += Size) { 5130b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer MCInst Inst; 5140b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer 5152c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha if (DisAsm->getInstruction(Inst, Size, memoryObject, 5162c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha SectionAddr + Index, 5172c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha DebugOut, CommentStream)) { 5188b9da530e3637fd4afb33f80673178dcc74397f0Eli Bendersky outs() << format("%8" PRIx64 ":", SectionAddr + Index); 5198b9da530e3637fd4afb33f80673178dcc74397f0Eli Bendersky if (!NoShowRawInsn) { 5208b9da530e3637fd4afb33f80673178dcc74397f0Eli Bendersky outs() << "\t"; 5218b9da530e3637fd4afb33f80673178dcc74397f0Eli Bendersky DumpBytes(StringRef(Bytes.data() + Index, Size)); 5228b9da530e3637fd4afb33f80673178dcc74397f0Eli Bendersky } 5230b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer IP->printInst(&Inst, outs(), ""); 5242c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha outs() << CommentStream.str(); 5252c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha Comments.clear(); 5260b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer outs() << "\n"; 5270b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer } else { 5280b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer errs() << ToolName << ": warning: invalid instruction encoding\n"; 5290b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer if (Size == 0) 5300b8b771e9f2f251460a6f200c45efe9d55640d60Benjamin Kramer Size = 1; // skip illegible bytes 531685a2501b20baf688f6cc087f4b92bbafcd8028eBenjamin Kramer } 532942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer 533942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer // Print relocation for instruction. 534942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer while (rel_cur != rel_end) { 5350685e94895f26f96aa1032696e3150dd00aad1f3Owen Anderson bool hidden = false; 536942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer uint64_t addr; 537942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer SmallString<16> name; 538942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer SmallString<32> val; 5390685e94895f26f96aa1032696e3150dd00aad1f3Owen Anderson 5400685e94895f26f96aa1032696e3150dd00aad1f3Owen Anderson // If this relocation is hidden, skip it. 5410685e94895f26f96aa1032696e3150dd00aad1f3Owen Anderson if (error(rel_cur->getHidden(hidden))) goto skip_print_rel; 5420685e94895f26f96aa1032696e3150dd00aad1f3Owen Anderson if (hidden) goto skip_print_rel; 5430685e94895f26f96aa1032696e3150dd00aad1f3Owen Anderson 544956ca7265c697107708468b7e1b2fd21f4185baeRafael Espindola if (error(rel_cur->getOffset(addr))) goto skip_print_rel; 545942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer // Stop when rel_cur's address is past the current instruction. 54634749ce4df9636188782c652dc9dc9c73d4bce11Owen Anderson if (addr >= Index + Size) break; 547942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer if (error(rel_cur->getTypeName(name))) goto skip_print_rel; 548942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer if (error(rel_cur->getValueString(val))) goto skip_print_rel; 549942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer 55036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines outs() << format(Fmt.data(), SectionAddr + addr) << name 55151cf8661637c114e4b4f178bd2677a6bb246be0dBenjamin Kramer << "\t" << val << "\n"; 552942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer 553942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer skip_print_rel: 554942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer ++rel_cur; 555942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer } 556685a2501b20baf688f6cc087f4b92bbafcd8028eBenjamin Kramer } 55792e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer } 55892e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer } 55992e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer} 56092e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer 56136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic void PrintRelocations(const ObjectFile *Obj) { 56236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines StringRef Fmt = Obj->getBytesInAddress() > 4 ? "%016" PRIx64 : 56336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines "%08" PRIx64; 56436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (const SectionRef &Section : Obj->sections()) { 56536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Section.relocation_begin() == Section.relocation_end()) 56627781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer continue; 56727781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer StringRef secname; 56836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error(Section.getName(secname))) 56936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines continue; 57027781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer outs() << "RELOCATION RECORDS FOR [" << secname << "]:\n"; 57136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (const RelocationRef &Reloc : Section.relocations()) { 5720685e94895f26f96aa1032696e3150dd00aad1f3Owen Anderson bool hidden; 57327781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer uint64_t address; 57427781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer SmallString<32> relocname; 57527781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer SmallString<32> valuestr; 57636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error(Reloc.getHidden(hidden))) 57736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines continue; 57836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (hidden) 57936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines continue; 58036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error(Reloc.getTypeName(relocname))) 58136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines continue; 58236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error(Reloc.getOffset(address))) 58336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines continue; 58436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error(Reloc.getValueString(valuestr))) 58536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines continue; 58636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines outs() << format(Fmt.data(), address) << " " << relocname << " " 58736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << valuestr << "\n"; 58827781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer } 58927781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer outs() << "\n"; 59027781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer } 59127781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer} 59227781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer 59336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic void PrintSectionHeaders(const ObjectFile *Obj) { 594023bb15beaac3744ce3a5d1f750d6e32829c7130Nick Lewycky outs() << "Sections:\n" 595023bb15beaac3744ce3a5d1f750d6e32829c7130Nick Lewycky "Idx Name Size Address Type\n"; 596023bb15beaac3744ce3a5d1f750d6e32829c7130Nick Lewycky unsigned i = 0; 59736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (const SectionRef &Section : Obj->sections()) { 598023bb15beaac3744ce3a5d1f750d6e32829c7130Nick Lewycky StringRef Name; 59936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error(Section.getName(Name))) 60036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 601023bb15beaac3744ce3a5d1f750d6e32829c7130Nick Lewycky uint64_t Address; 60236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error(Section.getAddress(Address))) 60336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 604023bb15beaac3744ce3a5d1f750d6e32829c7130Nick Lewycky uint64_t Size; 60536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error(Section.getSize(Size))) 60636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 607023bb15beaac3744ce3a5d1f750d6e32829c7130Nick Lewycky bool Text, Data, BSS; 60836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error(Section.isText(Text))) 60936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 61036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error(Section.isData(Data))) 61136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 61236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error(Section.isBSS(BSS))) 61336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 614023bb15beaac3744ce3a5d1f750d6e32829c7130Nick Lewycky std::string Type = (std::string(Text ? "TEXT " : "") + 61514a5f468d6b18b7637821e13e56fe56dd79d7cafMichael J. Spencer (Data ? "DATA " : "") + (BSS ? "BSS" : "")); 61636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines outs() << format("%3d %-13s %08" PRIx64 " %016" PRIx64 " %s\n", i, 61736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Name.str().c_str(), Size, Address, Type.c_str()); 618023bb15beaac3744ce3a5d1f750d6e32829c7130Nick Lewycky ++i; 619023bb15beaac3744ce3a5d1f750d6e32829c7130Nick Lewycky } 620023bb15beaac3744ce3a5d1f750d6e32829c7130Nick Lewycky} 621023bb15beaac3744ce3a5d1f750d6e32829c7130Nick Lewycky 62236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic void PrintSectionContents(const ObjectFile *Obj) { 623cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::error_code EC; 62436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (const SectionRef &Section : Obj->sections()) { 6251e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer StringRef Name; 6261e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer StringRef Contents; 6271e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer uint64_t BaseAddr; 6280eaa6f675cafb2bb1b6a6210797c1d7b3da3ff9fAlexey Samsonov bool BSS; 62936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error(Section.getName(Name))) 63036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines continue; 63136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error(Section.getContents(Contents))) 63236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines continue; 63336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error(Section.getAddress(BaseAddr))) 63436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines continue; 63536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error(Section.isBSS(BSS))) 63636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines continue; 6371e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer 6381e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer outs() << "Contents of section " << Name << ":\n"; 6390eaa6f675cafb2bb1b6a6210797c1d7b3da3ff9fAlexey Samsonov if (BSS) { 6400eaa6f675cafb2bb1b6a6210797c1d7b3da3ff9fAlexey Samsonov outs() << format("<skipping contents of bss section at [%04" PRIx64 6410eaa6f675cafb2bb1b6a6210797c1d7b3da3ff9fAlexey Samsonov ", %04" PRIx64 ")>\n", BaseAddr, 6420eaa6f675cafb2bb1b6a6210797c1d7b3da3ff9fAlexey Samsonov BaseAddr + Contents.size()); 6430eaa6f675cafb2bb1b6a6210797c1d7b3da3ff9fAlexey Samsonov continue; 6440eaa6f675cafb2bb1b6a6210797c1d7b3da3ff9fAlexey Samsonov } 6451e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer 6461e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer // Dump out the content as hex and printable ascii characters. 6471e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer for (std::size_t addr = 0, end = Contents.size(); addr < end; addr += 16) { 64851cf8661637c114e4b4f178bd2677a6bb246be0dBenjamin Kramer outs() << format(" %04" PRIx64 " ", BaseAddr + addr); 6491e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer // Dump line of hex. 6501e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer for (std::size_t i = 0; i < 16; ++i) { 6511e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer if (i != 0 && i % 4 == 0) 6521e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer outs() << ' '; 6531e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer if (addr + i < end) 6541e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer outs() << hexdigit((Contents[addr + i] >> 4) & 0xF, true) 6551e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer << hexdigit(Contents[addr + i] & 0xF, true); 6561e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer else 6571e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer outs() << " "; 6581e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer } 6591e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer // Print ascii. 6601e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer outs() << " "; 6611e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer for (std::size_t i = 0; i < 16 && addr + i < end; ++i) { 66287d0b9ed1462705dd9bf1cb7f67d0bf03af776c8Guy Benyei if (std::isprint(static_cast<unsigned char>(Contents[addr + i]) & 0xFF)) 6631e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer outs() << Contents[addr + i]; 6641e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer else 6651e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer outs() << "."; 6661e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer } 6671e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer outs() << "\n"; 6681e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer } 6691e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer } 6701e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer} 6711e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer 67222ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencerstatic void PrintCOFFSymbolTable(const COFFObjectFile *coff) { 67322ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencer const coff_file_header *header; 674dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (error(coff->getHeader(header))) 675dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return; 676dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 677dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines for (unsigned SI = 0, SE = header->NumberOfSymbols; SI != SE; ++SI) { 678dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const coff_symbol *Symbol; 679dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines StringRef Name; 680dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (error(coff->getSymbol(SI, Symbol))) 681dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return; 682dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 683dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (error(coff->getSymbolName(Symbol, Name))) 684dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return; 685dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 686dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines outs() << "[" << format("%2d", SI) << "]" 687dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines << "(sec " << format("%2d", int(Symbol->SectionNumber)) << ")" 688dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines << "(fl 0x00)" // Flag bits, which COFF doesn't have. 689dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines << "(ty " << format("%3x", unsigned(Symbol->Type)) << ")" 690dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines << "(scl " << format("%3x", unsigned(Symbol->StorageClass)) << ") " 691dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines << "(nx " << unsigned(Symbol->NumberOfAuxSymbols) << ") " 692dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines << "0x" << format("%08x", unsigned(Symbol->Value)) << " " 693dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines << Name << "\n"; 694dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 695dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines for (unsigned AI = 0, AE = Symbol->NumberOfAuxSymbols; AI < AE; ++AI, ++SI) { 696dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (Symbol->isSectionDefinition()) { 69722ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencer const coff_aux_section_definition *asd; 698dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (error(coff->getAuxSymbol<coff_aux_section_definition>(SI + 1, asd))) 69922ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencer return; 700dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 70122ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencer outs() << "AUX " 70222ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencer << format("scnlen 0x%x nreloc %d nlnno %d checksum 0x%x " 70322ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencer , unsigned(asd->Length) 70422ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencer , unsigned(asd->NumberOfRelocations) 70522ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencer , unsigned(asd->NumberOfLinenumbers) 70622ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencer , unsigned(asd->CheckSum)) 70722ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencer << format("assoc %d comdat %d\n" 70822ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencer , unsigned(asd->Number) 70922ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencer , unsigned(asd->Selection)); 710dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } else if (Symbol->isFileRecord()) { 711dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const coff_aux_file *AF; 712dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (error(coff->getAuxSymbol<coff_aux_file>(SI + 1, AF))) 713dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return; 714dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 715dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines StringRef Name(AF->FileName, 716dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Symbol->NumberOfAuxSymbols * COFF::SymbolSize); 717dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines outs() << "AUX " << Name.rtrim(StringRef("\0", 1)) << '\n'; 718dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 719dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines SI = SI + Symbol->NumberOfAuxSymbols; 720dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines break; 721dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } else { 72222ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencer outs() << "AUX Unknown\n"; 723dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 72422ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencer } 72522ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencer } 72622ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencer} 72722ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencer 72822ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencerstatic void PrintSymbolTable(const ObjectFile *o) { 72922ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencer outs() << "SYMBOL TABLE:\n"; 73022ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencer 73136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (const COFFObjectFile *coff = dyn_cast<const COFFObjectFile>(o)) { 73222ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencer PrintCOFFSymbolTable(coff); 73336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 73436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 73536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (const SymbolRef &Symbol : o->symbols()) { 73636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines StringRef Name; 73736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t Address; 73836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SymbolRef::Type Type; 73936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t Size; 74036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint32_t Flags = Symbol.getFlags(); 74136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines section_iterator Section = o->section_end(); 74236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error(Symbol.getName(Name))) 74336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines continue; 74436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error(Symbol.getAddress(Address))) 74536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines continue; 74636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error(Symbol.getType(Type))) 74736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines continue; 74836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error(Symbol.getSize(Size))) 74936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines continue; 75036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error(Symbol.getSection(Section))) 75136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines continue; 75236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 75336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool Global = Flags & SymbolRef::SF_Global; 75436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool Weak = Flags & SymbolRef::SF_Weak; 75536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool Absolute = Flags & SymbolRef::SF_Absolute; 75636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 75736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Address == UnknownAddressOrSize) 75836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Address = 0; 75936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Size == UnknownAddressOrSize) 76036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Size = 0; 76136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines char GlobLoc = ' '; 76236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Type != SymbolRef::ST_Unknown) 76336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines GlobLoc = Global ? 'g' : 'l'; 76436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines char Debug = (Type == SymbolRef::ST_Debug || Type == SymbolRef::ST_File) 76536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ? 'd' : ' '; 76636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines char FileFunc = ' '; 76736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Type == SymbolRef::ST_File) 76836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines FileFunc = 'f'; 76936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else if (Type == SymbolRef::ST_Function) 77036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines FileFunc = 'F'; 77136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 77236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const char *Fmt = o->getBytesInAddress() > 4 ? "%016" PRIx64 : 77336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines "%08" PRIx64; 77436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 77536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines outs() << format(Fmt, Address) << " " 77636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << GlobLoc // Local -> 'l', Global -> 'g', Neither -> ' ' 77736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << (Weak ? 'w' : ' ') // Weak? 77836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << ' ' // Constructor. Not supported yet. 77936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << ' ' // Warning. Not supported yet. 78036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << ' ' // Indirect reference to another symbol. 78136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << Debug // Debugging (d) or dynamic (D) symbol. 78236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << FileFunc // Name of function (F), file (f) or object (O). 78336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << ' '; 78436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Absolute) { 78536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines outs() << "*ABS*"; 78636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else if (Section == o->section_end()) { 78736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines outs() << "*UND*"; 78836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else { 78936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (const MachOObjectFile *MachO = 79036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines dyn_cast<const MachOObjectFile>(o)) { 79136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DataRefImpl DR = Section->getRawDataRefImpl(); 79236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines StringRef SegmentName = MachO->getSectionFinalSegmentName(DR); 79336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines outs() << SegmentName << ","; 79422ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencer } 79536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines StringRef SectionName; 79636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error(Section->getName(SectionName))) 79736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SectionName = ""; 79836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines outs() << SectionName; 79922ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencer } 80036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines outs() << '\t' 80136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << format("%08" PRIx64 " ", Size) 80236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << Name 80336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << '\n'; 80422ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencer } 80522ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencer} 80622ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencer 807eef7b6219ebe5d0ded0be4adb3003055fa8a63c4Michael J. Spencerstatic void PrintUnwindInfo(const ObjectFile *o) { 808eef7b6219ebe5d0ded0be4adb3003055fa8a63c4Michael J. Spencer outs() << "Unwind info:\n\n"; 809eef7b6219ebe5d0ded0be4adb3003055fa8a63c4Michael J. Spencer 810eef7b6219ebe5d0ded0be4adb3003055fa8a63c4Michael J. Spencer if (const COFFObjectFile *coff = dyn_cast<COFFObjectFile>(o)) { 811eef7b6219ebe5d0ded0be4adb3003055fa8a63c4Michael J. Spencer printCOFFUnwindInfo(coff); 812eef7b6219ebe5d0ded0be4adb3003055fa8a63c4Michael J. Spencer } else { 813eef7b6219ebe5d0ded0be4adb3003055fa8a63c4Michael J. Spencer // TODO: Extract DWARF dump tool to objdump. 814eef7b6219ebe5d0ded0be4adb3003055fa8a63c4Michael J. Spencer errs() << "This operation is only currently supported " 815eef7b6219ebe5d0ded0be4adb3003055fa8a63c4Michael J. Spencer "for COFF object files.\n"; 816eef7b6219ebe5d0ded0be4adb3003055fa8a63c4Michael J. Spencer return; 817eef7b6219ebe5d0ded0be4adb3003055fa8a63c4Michael J. Spencer } 818eef7b6219ebe5d0ded0be4adb3003055fa8a63c4Michael J. Spencer} 819eef7b6219ebe5d0ded0be4adb3003055fa8a63c4Michael J. Spencer 820a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyamastatic void printPrivateFileHeader(const ObjectFile *o) { 821a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama if (o->isELF()) { 822a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama printELFFileHeader(o); 823a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama } else if (o->isCOFF()) { 824a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama printCOFFFileHeader(o); 825a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama } 826a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama} 827a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama 82827781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencerstatic void DumpObject(const ObjectFile *o) { 8291e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer outs() << '\n'; 8301e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer outs() << o->getFileName() 8311e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer << ":\tfile format " << o->getFileFormatName() << "\n\n"; 8321e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer 83327781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer if (Disassemble) 834942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer DisassembleObject(o, Relocations); 835942eb009114ef9a2e95e236790faa7a3c04bc2baMichael J. Spencer if (Relocations && !Disassemble) 83627781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer PrintRelocations(o); 837023bb15beaac3744ce3a5d1f750d6e32829c7130Nick Lewycky if (SectionHeaders) 838023bb15beaac3744ce3a5d1f750d6e32829c7130Nick Lewycky PrintSectionHeaders(o); 8391e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer if (SectionContents) 8401e8ba3fa21326de4ef5bf908f6bfbf2852e04794Michael J. Spencer PrintSectionContents(o); 84122ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencer if (SymbolTable) 84222ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencer PrintSymbolTable(o); 843eef7b6219ebe5d0ded0be4adb3003055fa8a63c4Michael J. Spencer if (UnwindInfo) 844eef7b6219ebe5d0ded0be4adb3003055fa8a63c4Michael J. Spencer PrintUnwindInfo(o); 845a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama if (PrivateHeaders) 846a6610ee882fcb8bcad60d53fc52b80f00a3fddaeRui Ueyama printPrivateFileHeader(o); 84727781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer} 84827781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer 84927781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer/// @brief Dump each object file in \a a; 85027781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencerstatic void DumpArchive(const Archive *a) { 85136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (Archive::child_iterator i = a->child_begin(), e = a->child_end(); i != e; 85236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ++i) { 853cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ErrorOr<std::unique_ptr<Binary>> ChildOrErr = i->getAsBinary(); 854cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (std::error_code EC = ChildOrErr.getError()) { 855f81285c0c507908b429a2c4cbd0683d624d375f9Michael J. Spencer // Ignore non-object files. 85636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (EC != object_error::invalid_file_type) 85736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines errs() << ToolName << ": '" << a->getFileName() << "': " << EC.message() 858f81285c0c507908b429a2c4cbd0683d624d375f9Michael J. Spencer << ".\n"; 85927781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer continue; 86027781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer } 861cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (ObjectFile *o = dyn_cast<ObjectFile>(&*ChildOrErr.get())) 86227781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer DumpObject(o); 86327781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer else 86427781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer errs() << ToolName << ": '" << a->getFileName() << "': " 86527781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer << "Unrecognized file type.\n"; 86627781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer } 86727781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer} 86827781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer 86927781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer/// @brief Open file and figure out how to dump it. 87027781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencerstatic void DumpInput(StringRef file) { 87127781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer // If file isn't stdin, check that it exists. 87227781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer if (file != "-" && !sys::fs::exists(file)) { 87327781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer errs() << ToolName << ": '" << file << "': " << "No such file\n"; 87427781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer return; 87527781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer } 87627781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer 877cef81b37c77978cd4dddb4a5ad13564793ded155Rafael Espindola if (MachOOpt && Disassemble) { 87827781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer DisassembleInputMachO(file); 87927781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer return; 88027781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer } 88127781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer 88227781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer // Attempt to open the binary. 88336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ErrorOr<Binary *> BinaryOrErr = createBinary(file); 884cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (std::error_code EC = BinaryOrErr.getError()) { 88536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines errs() << ToolName << ": '" << file << "': " << EC.message() << ".\n"; 88627781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer return; 88727781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer } 88836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<Binary> binary(BinaryOrErr.get()); 88927781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer 8903f5d1a2396915ebff20ce4f5d668ee5c839d1d91Jim Grosbach if (Archive *a = dyn_cast<Archive>(binary.get())) 89127781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer DumpArchive(a); 8923f5d1a2396915ebff20ce4f5d668ee5c839d1d91Jim Grosbach else if (ObjectFile *o = dyn_cast<ObjectFile>(binary.get())) 89327781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer DumpObject(o); 8943f5d1a2396915ebff20ce4f5d668ee5c839d1d91Jim Grosbach else 89527781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer errs() << ToolName << ": '" << file << "': " << "Unrecognized file type.\n"; 89627781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer} 89727781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer 89892e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencerint main(int argc, char **argv) { 89992e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer // Print a stack trace if we signal out. 90092e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer sys::PrintStackTraceOnErrorSignal(); 90192e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer PrettyStackTraceProgram X(argc, argv); 90292e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. 90392e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer 90492e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer // Initialize targets and assembly printers/parsers. 90592e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer llvm::InitializeAllTargetInfos(); 906e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng llvm::InitializeAllTargetMCs(); 90792e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer llvm::InitializeAllAsmParsers(); 90892e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer llvm::InitializeAllDisassemblers(); 90992e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer 910ff204963cbcd7c68d59f3bba5bfa2797ea0cebaePete Cooper // Register the target printer for --version. 911ff204963cbcd7c68d59f3bba5bfa2797ea0cebaePete Cooper cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion); 912ff204963cbcd7c68d59f3bba5bfa2797ea0cebaePete Cooper 91392e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer cl::ParseCommandLineOptions(argc, argv, "llvm object file dumper\n"); 91492e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer TripleName = Triple::normalize(TripleName); 91592e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer 91692e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer ToolName = argv[0]; 91792e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer 91892e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer // Defaults to a.out if no filenames specified. 91992e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer if (InputFilenames.size() == 0) 92092e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer InputFilenames.push_back("a.out"); 92192e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer 92222ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencer if (!Disassemble 92322ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencer && !Relocations 92422ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencer && !SectionHeaders 92522ff0f33dbfe99d7308658f07986c1014ea5aff2Michael J. Spencer && !SectionContents 926eef7b6219ebe5d0ded0be4adb3003055fa8a63c4Michael J. Spencer && !SymbolTable 927b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer && !UnwindInfo 928b2c064c6954c9bfa49b7a7e3223df5e7849464c0Michael J. Spencer && !PrivateHeaders) { 92992e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer cl::PrintHelpMessage(); 93092e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer return 2; 93192e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer } 93292e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer 93327781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer std::for_each(InputFilenames.begin(), InputFilenames.end(), 93427781b78e111a1d276dd3cd604b0cdfa662f1f4eMichael J. Spencer DumpInput); 93592e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer 93692e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer return 0; 93792e1deb05182c116bf39bec5f4df3769b5abc7f4Michael J. Spencer} 938