Home | History | Annotate | Download | only in llvm-objdump
      1 //===-- llvm-objdump.cpp - Object file dumping utility for llvm -----------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This program is a utility that works like binutils "objdump", that is, it
     11 // dumps out a plethora of information about an object file depending on the
     12 // flags.
     13 //
     14 //===----------------------------------------------------------------------===//
     15 
     16 #include "llvm-objdump.h"
     17 #include "MCFunction.h"
     18 #include "llvm/Object/Archive.h"
     19 #include "llvm/Object/ObjectFile.h"
     20 #include "llvm/ADT/OwningPtr.h"
     21 #include "llvm/ADT/Triple.h"
     22 #include "llvm/ADT/STLExtras.h"
     23 #include "llvm/MC/MCAsmInfo.h"
     24 #include "llvm/MC/MCDisassembler.h"
     25 #include "llvm/MC/MCInst.h"
     26 #include "llvm/MC/MCInstPrinter.h"
     27 #include "llvm/MC/MCSubtargetInfo.h"
     28 #include "llvm/Support/Casting.h"
     29 #include "llvm/Support/CommandLine.h"
     30 #include "llvm/Support/Debug.h"
     31 #include "llvm/Support/FileSystem.h"
     32 #include "llvm/Support/Format.h"
     33 #include "llvm/Support/GraphWriter.h"
     34 #include "llvm/Support/Host.h"
     35 #include "llvm/Support/ManagedStatic.h"
     36 #include "llvm/Support/MemoryBuffer.h"
     37 #include "llvm/Support/MemoryObject.h"
     38 #include "llvm/Support/PrettyStackTrace.h"
     39 #include "llvm/Support/Signals.h"
     40 #include "llvm/Support/SourceMgr.h"
     41 #include "llvm/Support/TargetRegistry.h"
     42 #include "llvm/Support/TargetSelect.h"
     43 #include "llvm/Support/raw_ostream.h"
     44 #include "llvm/Support/system_error.h"
     45 #include <algorithm>
     46 #include <cstring>
     47 using namespace llvm;
     48 using namespace object;
     49 
     50 static cl::list<std::string>
     51 InputFilenames(cl::Positional, cl::desc("<input object files>"),cl::ZeroOrMore);
     52 
     53 static cl::opt<bool>
     54 Disassemble("disassemble",
     55   cl::desc("Display assembler mnemonics for the machine instructions"));
     56 static cl::alias
     57 Disassembled("d", cl::desc("Alias for --disassemble"),
     58              cl::aliasopt(Disassemble));
     59 
     60 static cl::opt<bool>
     61 Relocations("r", cl::desc("Display the relocation entries in the file"));
     62 
     63 static cl::opt<bool>
     64 MachO("macho", cl::desc("Use MachO specific object file parser"));
     65 static cl::alias
     66 MachOm("m", cl::desc("Alias for --macho"), cl::aliasopt(MachO));
     67 
     68 cl::opt<std::string>
     69 llvm::TripleName("triple", cl::desc("Target triple to disassemble for, "
     70                                     "see -version for available targets"));
     71 
     72 cl::opt<std::string>
     73 llvm::ArchName("arch", cl::desc("Target arch to disassemble for, "
     74                                 "see -version for available targets"));
     75 
     76 static cl::opt<bool>
     77 SectionHeaders("section-headers", cl::desc("Display summaries of the headers "
     78                                            "for each section."));
     79 static cl::alias
     80 SectionHeadersShort("headers", cl::desc("Alias for --section-headers"),
     81                     cl::aliasopt(SectionHeaders));
     82 static cl::alias
     83 SectionHeadersShorter("h", cl::desc("Alias for --section-headers"),
     84                       cl::aliasopt(SectionHeaders));
     85 
     86 static StringRef ToolName;
     87 
     88 static bool error(error_code ec) {
     89   if (!ec) return false;
     90 
     91   outs() << ToolName << ": error reading file: " << ec.message() << ".\n";
     92   outs().flush();
     93   return true;
     94 }
     95 
     96 static const Target *GetTarget(const ObjectFile *Obj = NULL) {
     97   // Figure out the target triple.
     98   llvm::Triple TT("unknown-unknown-unknown");
     99   if (TripleName.empty()) {
    100     if (Obj)
    101       TT.setArch(Triple::ArchType(Obj->getArch()));
    102   } else
    103     TT.setTriple(Triple::normalize(TripleName));
    104 
    105   if (!ArchName.empty())
    106     TT.setArchName(ArchName);
    107 
    108   TripleName = TT.str();
    109 
    110   // Get the target specific parser.
    111   std::string Error;
    112   const Target *TheTarget = TargetRegistry::lookupTarget(TripleName, Error);
    113   if (TheTarget)
    114     return TheTarget;
    115 
    116   errs() << ToolName << ": error: unable to get target for '" << TripleName
    117          << "', see --version and --triple.\n";
    118   return 0;
    119 }
    120 
    121 void llvm::DumpBytes(StringRef bytes) {
    122   static const char hex_rep[] = "0123456789abcdef";
    123   // FIXME: The real way to do this is to figure out the longest instruction
    124   //        and align to that size before printing. I'll fix this when I get
    125   //        around to outputting relocations.
    126   // 15 is the longest x86 instruction
    127   // 3 is for the hex rep of a byte + a space.
    128   // 1 is for the null terminator.
    129   enum { OutputSize = (15 * 3) + 1 };
    130   char output[OutputSize];
    131 
    132   assert(bytes.size() <= 15
    133     && "DumpBytes only supports instructions of up to 15 bytes");
    134   memset(output, ' ', sizeof(output));
    135   unsigned index = 0;
    136   for (StringRef::iterator i = bytes.begin(),
    137                            e = bytes.end(); i != e; ++i) {
    138     output[index] = hex_rep[(*i & 0xF0) >> 4];
    139     output[index + 1] = hex_rep[*i & 0xF];
    140     index += 3;
    141   }
    142 
    143   output[sizeof(output) - 1] = 0;
    144   outs() << output;
    145 }
    146 
    147 static bool RelocAddressLess(RelocationRef a, RelocationRef b) {
    148   uint64_t a_addr, b_addr;
    149   if (error(a.getAddress(a_addr))) return false;
    150   if (error(b.getAddress(b_addr))) return false;
    151   return a_addr < b_addr;
    152 }
    153 
    154 static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
    155   const Target *TheTarget = GetTarget(Obj);
    156   if (!TheTarget) {
    157     // GetTarget prints out stuff.
    158     return;
    159   }
    160 
    161   outs() << '\n';
    162   outs() << Obj->getFileName()
    163          << ":\tfile format " << Obj->getFileFormatName() << "\n\n";
    164 
    165   error_code ec;
    166   for (section_iterator i = Obj->begin_sections(),
    167                         e = Obj->end_sections();
    168                         i != e; i.increment(ec)) {
    169     if (error(ec)) break;
    170     bool text;
    171     if (error(i->isText(text))) break;
    172     if (!text) continue;
    173 
    174     uint64_t SectionAddr;
    175     if (error(i->getAddress(SectionAddr))) break;
    176 
    177     // Make a list of all the symbols in this section.
    178     std::vector<std::pair<uint64_t, StringRef> > Symbols;
    179     for (symbol_iterator si = Obj->begin_symbols(),
    180                          se = Obj->end_symbols();
    181                          si != se; si.increment(ec)) {
    182       bool contains;
    183       if (!error(i->containsSymbol(*si, contains)) && contains) {
    184         uint64_t Address;
    185         if (error(si->getOffset(Address))) break;
    186         StringRef Name;
    187         if (error(si->getName(Name))) break;
    188         Symbols.push_back(std::make_pair(Address, Name));
    189       }
    190     }
    191 
    192     // Sort the symbols by address, just in case they didn't come in that way.
    193     array_pod_sort(Symbols.begin(), Symbols.end());
    194 
    195     // Make a list of all the relocations for this section.
    196     std::vector<RelocationRef> Rels;
    197     if (InlineRelocs) {
    198       for (relocation_iterator ri = i->begin_relocations(),
    199                                re = i->end_relocations();
    200                               ri != re; ri.increment(ec)) {
    201         if (error(ec)) break;
    202         Rels.push_back(*ri);
    203       }
    204     }
    205 
    206     // Sort relocations by address.
    207     std::sort(Rels.begin(), Rels.end(), RelocAddressLess);
    208 
    209     StringRef name;
    210     if (error(i->getName(name))) break;
    211     outs() << "Disassembly of section " << name << ':';
    212 
    213     // If the section has no symbols just insert a dummy one and disassemble
    214     // the whole section.
    215     if (Symbols.empty())
    216       Symbols.push_back(std::make_pair(0, name));
    217 
    218     // Set up disassembler.
    219     OwningPtr<const MCAsmInfo> AsmInfo(TheTarget->createMCAsmInfo(TripleName));
    220 
    221     if (!AsmInfo) {
    222       errs() << "error: no assembly info for target " << TripleName << "\n";
    223       return;
    224     }
    225 
    226     OwningPtr<const MCSubtargetInfo> STI(
    227       TheTarget->createMCSubtargetInfo(TripleName, "", ""));
    228 
    229     if (!STI) {
    230       errs() << "error: no subtarget info for target " << TripleName << "\n";
    231       return;
    232     }
    233 
    234     OwningPtr<const MCDisassembler> DisAsm(
    235       TheTarget->createMCDisassembler(*STI));
    236     if (!DisAsm) {
    237       errs() << "error: no disassembler for target " << TripleName << "\n";
    238       return;
    239     }
    240 
    241     int AsmPrinterVariant = AsmInfo->getAssemblerDialect();
    242     OwningPtr<MCInstPrinter> IP(TheTarget->createMCInstPrinter(
    243                                 AsmPrinterVariant, *AsmInfo, *STI));
    244     if (!IP) {
    245       errs() << "error: no instruction printer for target " << TripleName
    246              << '\n';
    247       return;
    248     }
    249 
    250     StringRef Bytes;
    251     if (error(i->getContents(Bytes))) break;
    252     StringRefMemoryObject memoryObject(Bytes);
    253     uint64_t Size;
    254     uint64_t Index;
    255     uint64_t SectSize;
    256     if (error(i->getSize(SectSize))) break;
    257 
    258     std::vector<RelocationRef>::const_iterator rel_cur = Rels.begin();
    259     std::vector<RelocationRef>::const_iterator rel_end = Rels.end();
    260     // Disassemble symbol by symbol.
    261     for (unsigned si = 0, se = Symbols.size(); si != se; ++si) {
    262       uint64_t Start = Symbols[si].first;
    263       uint64_t End;
    264       // The end is either the size of the section or the beginning of the next
    265       // symbol.
    266       if (si == se - 1)
    267         End = SectSize;
    268       // Make sure this symbol takes up space.
    269       else if (Symbols[si + 1].first != Start)
    270         End = Symbols[si + 1].first - 1;
    271       else
    272         // This symbol has the same address as the next symbol. Skip it.
    273         continue;
    274 
    275       outs() << '\n' << Symbols[si].second << ":\n";
    276 
    277 #ifndef NDEBUG
    278         raw_ostream &DebugOut = DebugFlag ? dbgs() : nulls();
    279 #else
    280         raw_ostream &DebugOut = nulls();
    281 #endif
    282 
    283       for (Index = Start; Index < End; Index += Size) {
    284         MCInst Inst;
    285 
    286         if (DisAsm->getInstruction(Inst, Size, memoryObject, Index,
    287                                    DebugOut, nulls())) {
    288           outs() << format("%8"PRIx64":\t", SectionAddr + Index);
    289           DumpBytes(StringRef(Bytes.data() + Index, Size));
    290           IP->printInst(&Inst, outs(), "");
    291           outs() << "\n";
    292         } else {
    293           errs() << ToolName << ": warning: invalid instruction encoding\n";
    294           if (Size == 0)
    295             Size = 1; // skip illegible bytes
    296         }
    297 
    298         // Print relocation for instruction.
    299         while (rel_cur != rel_end) {
    300           uint64_t addr;
    301           SmallString<16> name;
    302           SmallString<32> val;
    303           if (error(rel_cur->getAddress(addr))) goto skip_print_rel;
    304           // Stop when rel_cur's address is past the current instruction.
    305           if (addr > Index + Size) break;
    306           if (error(rel_cur->getTypeName(name))) goto skip_print_rel;
    307           if (error(rel_cur->getValueString(val))) goto skip_print_rel;
    308 
    309           outs() << format("\t\t\t%8"PRIx64": ", SectionAddr + addr) << name << "\t"
    310                  << val << "\n";
    311 
    312         skip_print_rel:
    313           ++rel_cur;
    314         }
    315       }
    316     }
    317   }
    318 }
    319 
    320 static void PrintRelocations(const ObjectFile *o) {
    321   error_code ec;
    322   for (section_iterator si = o->begin_sections(), se = o->end_sections();
    323                                                   si != se; si.increment(ec)){
    324     if (error(ec)) return;
    325     if (si->begin_relocations() == si->end_relocations())
    326       continue;
    327     StringRef secname;
    328     if (error(si->getName(secname))) continue;
    329     outs() << "RELOCATION RECORDS FOR [" << secname << "]:\n";
    330     for (relocation_iterator ri = si->begin_relocations(),
    331                              re = si->end_relocations();
    332                              ri != re; ri.increment(ec)) {
    333       if (error(ec)) return;
    334 
    335       uint64_t address;
    336       SmallString<32> relocname;
    337       SmallString<32> valuestr;
    338       if (error(ri->getTypeName(relocname))) continue;
    339       if (error(ri->getAddress(address))) continue;
    340       if (error(ri->getValueString(valuestr))) continue;
    341       outs() << address << " " << relocname << " " << valuestr << "\n";
    342     }
    343     outs() << "\n";
    344   }
    345 }
    346 
    347 static void PrintSectionHeaders(const ObjectFile *o) {
    348   outs() << "Sections:\n"
    349             "Idx Name          Size      Address          Type\n";
    350   error_code ec;
    351   unsigned i = 0;
    352   for (section_iterator si = o->begin_sections(), se = o->end_sections();
    353                                                   si != se; si.increment(ec)) {
    354     if (error(ec)) return;
    355     StringRef Name;
    356     if (error(si->getName(Name))) return;
    357     uint64_t Address;
    358     if (error(si->getAddress(Address))) return;
    359     uint64_t Size;
    360     if (error(si->getSize(Size))) return;
    361     bool Text, Data, BSS;
    362     if (error(si->isText(Text))) return;
    363     if (error(si->isData(Data))) return;
    364     if (error(si->isBSS(BSS))) return;
    365     std::string Type = (std::string(Text ? "TEXT " : "") +
    366                         (Data ? "DATA " : "") + (BSS ? "BSS" : ""));
    367     outs() << format("%3d %-13s %09"PRIx64" %017"PRIx64" %s\n", i, Name.str().c_str(), Size,
    368                      Address, Type.c_str());
    369     ++i;
    370   }
    371 }
    372 
    373 static void DumpObject(const ObjectFile *o) {
    374   if (Disassemble)
    375     DisassembleObject(o, Relocations);
    376   if (Relocations && !Disassemble)
    377     PrintRelocations(o);
    378   if (SectionHeaders)
    379     PrintSectionHeaders(o);
    380 }
    381 
    382 /// @brief Dump each object file in \a a;
    383 static void DumpArchive(const Archive *a) {
    384   for (Archive::child_iterator i = a->begin_children(),
    385                                e = a->end_children(); i != e; ++i) {
    386     OwningPtr<Binary> child;
    387     if (error_code ec = i->getAsBinary(child)) {
    388       errs() << ToolName << ": '" << a->getFileName() << "': " << ec.message()
    389              << ".\n";
    390       continue;
    391     }
    392     if (ObjectFile *o = dyn_cast<ObjectFile>(child.get()))
    393       DumpObject(o);
    394     else
    395       errs() << ToolName << ": '" << a->getFileName() << "': "
    396               << "Unrecognized file type.\n";
    397   }
    398 }
    399 
    400 /// @brief Open file and figure out how to dump it.
    401 static void DumpInput(StringRef file) {
    402   // If file isn't stdin, check that it exists.
    403   if (file != "-" && !sys::fs::exists(file)) {
    404     errs() << ToolName << ": '" << file << "': " << "No such file\n";
    405     return;
    406   }
    407 
    408   if (MachO && Disassemble) {
    409     DisassembleInputMachO(file);
    410     return;
    411   }
    412 
    413   // Attempt to open the binary.
    414   OwningPtr<Binary> binary;
    415   if (error_code ec = createBinary(file, binary)) {
    416     errs() << ToolName << ": '" << file << "': " << ec.message() << ".\n";
    417     return;
    418   }
    419 
    420   if (Archive *a = dyn_cast<Archive>(binary.get())) {
    421     DumpArchive(a);
    422   } else if (ObjectFile *o = dyn_cast<ObjectFile>(binary.get())) {
    423     DumpObject(o);
    424   } else {
    425     errs() << ToolName << ": '" << file << "': " << "Unrecognized file type.\n";
    426   }
    427 }
    428 
    429 int main(int argc, char **argv) {
    430   // Print a stack trace if we signal out.
    431   sys::PrintStackTraceOnErrorSignal();
    432   PrettyStackTraceProgram X(argc, argv);
    433   llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.
    434 
    435   // Initialize targets and assembly printers/parsers.
    436   llvm::InitializeAllTargetInfos();
    437   llvm::InitializeAllTargetMCs();
    438   llvm::InitializeAllAsmParsers();
    439   llvm::InitializeAllDisassemblers();
    440 
    441   cl::ParseCommandLineOptions(argc, argv, "llvm object file dumper\n");
    442   TripleName = Triple::normalize(TripleName);
    443 
    444   ToolName = argv[0];
    445 
    446   // Defaults to a.out if no filenames specified.
    447   if (InputFilenames.size() == 0)
    448     InputFilenames.push_back("a.out");
    449 
    450   if (!Disassemble && !Relocations && !SectionHeaders) {
    451     cl::PrintHelpMessage();
    452     return 2;
    453   }
    454 
    455   std::for_each(InputFilenames.begin(), InputFilenames.end(),
    456                 DumpInput);
    457 
    458   return 0;
    459 }
    460