• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/COFF.h"
20 #include "llvm/Object/ObjectFile.h"
21 #include "llvm/ADT/OwningPtr.h"
22 #include "llvm/ADT/StringExtras.h"
23 #include "llvm/ADT/Triple.h"
24 #include "llvm/ADT/STLExtras.h"
25 #include "llvm/MC/MCAsmInfo.h"
26 #include "llvm/MC/MCDisassembler.h"
27 #include "llvm/MC/MCInst.h"
28 #include "llvm/MC/MCInstPrinter.h"
29 #include "llvm/MC/MCInstrInfo.h"
30 #include "llvm/MC/MCRegisterInfo.h"
31 #include "llvm/MC/MCSubtargetInfo.h"
32 #include "llvm/Support/Casting.h"
33 #include "llvm/Support/CommandLine.h"
34 #include "llvm/Support/Debug.h"
35 #include "llvm/Support/FileSystem.h"
36 #include "llvm/Support/Format.h"
37 #include "llvm/Support/GraphWriter.h"
38 #include "llvm/Support/Host.h"
39 #include "llvm/Support/ManagedStatic.h"
40 #include "llvm/Support/MemoryBuffer.h"
41 #include "llvm/Support/MemoryObject.h"
42 #include "llvm/Support/PrettyStackTrace.h"
43 #include "llvm/Support/Signals.h"
44 #include "llvm/Support/SourceMgr.h"
45 #include "llvm/Support/TargetRegistry.h"
46 #include "llvm/Support/TargetSelect.h"
47 #include "llvm/Support/raw_ostream.h"
48 #include "llvm/Support/system_error.h"
49 #include <algorithm>
50 #include <cctype>
51 #include <cstring>
52 using namespace llvm;
53 using namespace object;
54 
55 static cl::list<std::string>
56 InputFilenames(cl::Positional, cl::desc("<input object files>"),cl::ZeroOrMore);
57 
58 static cl::opt<bool>
59 Disassemble("disassemble",
60   cl::desc("Display assembler mnemonics for the machine instructions"));
61 static cl::alias
62 Disassembled("d", cl::desc("Alias for --disassemble"),
63              cl::aliasopt(Disassemble));
64 
65 static cl::opt<bool>
66 Relocations("r", cl::desc("Display the relocation entries in the file"));
67 
68 static cl::opt<bool>
69 SectionContents("s", cl::desc("Display the content of each section"));
70 
71 static cl::opt<bool>
72 SymbolTable("t", cl::desc("Display the symbol table"));
73 
74 static cl::opt<bool>
75 MachO("macho", cl::desc("Use MachO specific object file parser"));
76 static cl::alias
77 MachOm("m", cl::desc("Alias for --macho"), cl::aliasopt(MachO));
78 
79 cl::opt<std::string>
80 llvm::TripleName("triple", cl::desc("Target triple to disassemble for, "
81                                     "see -version for available targets"));
82 
83 cl::opt<std::string>
84 llvm::ArchName("arch", cl::desc("Target arch to disassemble for, "
85                                 "see -version for available targets"));
86 
87 static cl::opt<bool>
88 SectionHeaders("section-headers", cl::desc("Display summaries of the headers "
89                                            "for each section."));
90 static cl::alias
91 SectionHeadersShort("headers", cl::desc("Alias for --section-headers"),
92                     cl::aliasopt(SectionHeaders));
93 static cl::alias
94 SectionHeadersShorter("h", cl::desc("Alias for --section-headers"),
95                       cl::aliasopt(SectionHeaders));
96 
97 static cl::list<std::string>
98 MAttrs("mattr",
99   cl::CommaSeparated,
100   cl::desc("Target specific attributes"),
101   cl::value_desc("a1,+a2,-a3,..."));
102 
103 static StringRef ToolName;
104 
error(error_code ec)105 static bool error(error_code ec) {
106   if (!ec) return false;
107 
108   outs() << ToolName << ": error reading file: " << ec.message() << ".\n";
109   outs().flush();
110   return true;
111 }
112 
getTarget(const ObjectFile * Obj=NULL)113 static const Target *getTarget(const ObjectFile *Obj = NULL) {
114   // Figure out the target triple.
115   llvm::Triple TheTriple("unknown-unknown-unknown");
116   if (TripleName.empty()) {
117     if (Obj)
118       TheTriple.setArch(Triple::ArchType(Obj->getArch()));
119   } else
120     TheTriple.setTriple(Triple::normalize(TripleName));
121 
122   // Get the target specific parser.
123   std::string Error;
124   const Target *TheTarget = TargetRegistry::lookupTarget(ArchName, TheTriple,
125                                                          Error);
126   if (!TheTarget) {
127     errs() << ToolName << ": " << Error;
128     return 0;
129   }
130 
131   // Update the triple name and return the found target.
132   TripleName = TheTriple.getTriple();
133   return TheTarget;
134 }
135 
anchor()136 void llvm::StringRefMemoryObject::anchor() { }
137 
DumpBytes(StringRef bytes)138 void llvm::DumpBytes(StringRef bytes) {
139   static const char hex_rep[] = "0123456789abcdef";
140   // FIXME: The real way to do this is to figure out the longest instruction
141   //        and align to that size before printing. I'll fix this when I get
142   //        around to outputting relocations.
143   // 15 is the longest x86 instruction
144   // 3 is for the hex rep of a byte + a space.
145   // 1 is for the null terminator.
146   enum { OutputSize = (15 * 3) + 1 };
147   char output[OutputSize];
148 
149   assert(bytes.size() <= 15
150     && "DumpBytes only supports instructions of up to 15 bytes");
151   memset(output, ' ', sizeof(output));
152   unsigned index = 0;
153   for (StringRef::iterator i = bytes.begin(),
154                            e = bytes.end(); i != e; ++i) {
155     output[index] = hex_rep[(*i & 0xF0) >> 4];
156     output[index + 1] = hex_rep[*i & 0xF];
157     index += 3;
158   }
159 
160   output[sizeof(output) - 1] = 0;
161   outs() << output;
162 }
163 
RelocAddressLess(RelocationRef a,RelocationRef b)164 static bool RelocAddressLess(RelocationRef a, RelocationRef b) {
165   uint64_t a_addr, b_addr;
166   if (error(a.getAddress(a_addr))) return false;
167   if (error(b.getAddress(b_addr))) return false;
168   return a_addr < b_addr;
169 }
170 
DisassembleObject(const ObjectFile * Obj,bool InlineRelocs)171 static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
172   const Target *TheTarget = getTarget(Obj);
173   // getTarget() will have already issued a diagnostic if necessary, so
174   // just bail here if it failed.
175   if (!TheTarget)
176     return;
177 
178   // Package up features to be passed to target/subtarget
179   std::string FeaturesStr;
180   if (MAttrs.size()) {
181     SubtargetFeatures Features;
182     for (unsigned i = 0; i != MAttrs.size(); ++i)
183       Features.AddFeature(MAttrs[i]);
184     FeaturesStr = Features.getString();
185   }
186 
187   error_code ec;
188   for (section_iterator i = Obj->begin_sections(),
189                         e = Obj->end_sections();
190                         i != e; i.increment(ec)) {
191     if (error(ec)) break;
192     bool text;
193     if (error(i->isText(text))) break;
194     if (!text) continue;
195 
196     uint64_t SectionAddr;
197     if (error(i->getAddress(SectionAddr))) break;
198 
199     // Make a list of all the symbols in this section.
200     std::vector<std::pair<uint64_t, StringRef> > Symbols;
201     for (symbol_iterator si = Obj->begin_symbols(),
202                          se = Obj->end_symbols();
203                          si != se; si.increment(ec)) {
204       bool contains;
205       if (!error(i->containsSymbol(*si, contains)) && contains) {
206         uint64_t Address;
207         if (error(si->getAddress(Address))) break;
208         Address -= SectionAddr;
209 
210         StringRef Name;
211         if (error(si->getName(Name))) break;
212         Symbols.push_back(std::make_pair(Address, Name));
213       }
214     }
215 
216     // Sort the symbols by address, just in case they didn't come in that way.
217     array_pod_sort(Symbols.begin(), Symbols.end());
218 
219     // Make a list of all the relocations for this section.
220     std::vector<RelocationRef> Rels;
221     if (InlineRelocs) {
222       for (relocation_iterator ri = i->begin_relocations(),
223                                re = i->end_relocations();
224                                ri != re; ri.increment(ec)) {
225         if (error(ec)) break;
226         Rels.push_back(*ri);
227       }
228     }
229 
230     // Sort relocations by address.
231     std::sort(Rels.begin(), Rels.end(), RelocAddressLess);
232 
233     StringRef name;
234     if (error(i->getName(name))) break;
235     outs() << "Disassembly of section " << name << ':';
236 
237     // If the section has no symbols just insert a dummy one and disassemble
238     // the whole section.
239     if (Symbols.empty())
240       Symbols.push_back(std::make_pair(0, name));
241 
242     // Set up disassembler.
243     OwningPtr<const MCAsmInfo> AsmInfo(TheTarget->createMCAsmInfo(TripleName));
244 
245     if (!AsmInfo) {
246       errs() << "error: no assembly info for target " << TripleName << "\n";
247       return;
248     }
249 
250     OwningPtr<const MCSubtargetInfo> STI(
251       TheTarget->createMCSubtargetInfo(TripleName, "", FeaturesStr));
252 
253     if (!STI) {
254       errs() << "error: no subtarget info for target " << TripleName << "\n";
255       return;
256     }
257 
258     OwningPtr<const MCDisassembler> DisAsm(
259       TheTarget->createMCDisassembler(*STI));
260     if (!DisAsm) {
261       errs() << "error: no disassembler for target " << TripleName << "\n";
262       return;
263     }
264 
265     OwningPtr<const MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TripleName));
266     if (!MRI) {
267       errs() << "error: no register info for target " << TripleName << "\n";
268       return;
269     }
270 
271     OwningPtr<const MCInstrInfo> MII(TheTarget->createMCInstrInfo());
272     if (!MII) {
273       errs() << "error: no instruction info for target " << TripleName << "\n";
274       return;
275     }
276 
277     int AsmPrinterVariant = AsmInfo->getAssemblerDialect();
278     OwningPtr<MCInstPrinter> IP(TheTarget->createMCInstPrinter(
279                                 AsmPrinterVariant, *AsmInfo, *MII, *MRI, *STI));
280     if (!IP) {
281       errs() << "error: no instruction printer for target " << TripleName
282              << '\n';
283       return;
284     }
285 
286     StringRef Bytes;
287     if (error(i->getContents(Bytes))) break;
288     StringRefMemoryObject memoryObject(Bytes);
289     uint64_t Size;
290     uint64_t Index;
291     uint64_t SectSize;
292     if (error(i->getSize(SectSize))) break;
293 
294     std::vector<RelocationRef>::const_iterator rel_cur = Rels.begin();
295     std::vector<RelocationRef>::const_iterator rel_end = Rels.end();
296     // Disassemble symbol by symbol.
297     for (unsigned si = 0, se = Symbols.size(); si != se; ++si) {
298       uint64_t Start = Symbols[si].first;
299       uint64_t End;
300       // The end is either the size of the section or the beginning of the next
301       // symbol.
302       if (si == se - 1)
303         End = SectSize;
304       // Make sure this symbol takes up space.
305       else if (Symbols[si + 1].first != Start)
306         End = Symbols[si + 1].first - 1;
307       else
308         // This symbol has the same address as the next symbol. Skip it.
309         continue;
310 
311       outs() << '\n' << Symbols[si].second << ":\n";
312 
313 #ifndef NDEBUG
314         raw_ostream &DebugOut = DebugFlag ? dbgs() : nulls();
315 #else
316         raw_ostream &DebugOut = nulls();
317 #endif
318 
319       for (Index = Start; Index < End; Index += Size) {
320         MCInst Inst;
321 
322         if (DisAsm->getInstruction(Inst, Size, memoryObject, Index,
323                                    DebugOut, nulls())) {
324           outs() << format("%8" PRIx64 ":\t", SectionAddr + Index);
325           DumpBytes(StringRef(Bytes.data() + Index, Size));
326           IP->printInst(&Inst, outs(), "");
327           outs() << "\n";
328         } else {
329           errs() << ToolName << ": warning: invalid instruction encoding\n";
330           if (Size == 0)
331             Size = 1; // skip illegible bytes
332         }
333 
334         // Print relocation for instruction.
335         while (rel_cur != rel_end) {
336           bool hidden = false;
337           uint64_t addr;
338           SmallString<16> name;
339           SmallString<32> val;
340 
341           // If this relocation is hidden, skip it.
342           if (error(rel_cur->getHidden(hidden))) goto skip_print_rel;
343           if (hidden) goto skip_print_rel;
344 
345           if (error(rel_cur->getAddress(addr))) goto skip_print_rel;
346           // Stop when rel_cur's address is past the current instruction.
347           if (addr >= Index + Size) break;
348           if (error(rel_cur->getTypeName(name))) goto skip_print_rel;
349           if (error(rel_cur->getValueString(val))) goto skip_print_rel;
350 
351           outs() << format("\t\t\t%8" PRIx64 ": ", SectionAddr + addr) << name
352                  << "\t" << val << "\n";
353 
354         skip_print_rel:
355           ++rel_cur;
356         }
357       }
358     }
359   }
360 }
361 
PrintRelocations(const ObjectFile * o)362 static void PrintRelocations(const ObjectFile *o) {
363   error_code ec;
364   for (section_iterator si = o->begin_sections(), se = o->end_sections();
365                                                   si != se; si.increment(ec)){
366     if (error(ec)) return;
367     if (si->begin_relocations() == si->end_relocations())
368       continue;
369     StringRef secname;
370     if (error(si->getName(secname))) continue;
371     outs() << "RELOCATION RECORDS FOR [" << secname << "]:\n";
372     for (relocation_iterator ri = si->begin_relocations(),
373                              re = si->end_relocations();
374                              ri != re; ri.increment(ec)) {
375       if (error(ec)) return;
376 
377       bool hidden;
378       uint64_t address;
379       SmallString<32> relocname;
380       SmallString<32> valuestr;
381       if (error(ri->getHidden(hidden))) continue;
382       if (hidden) continue;
383       if (error(ri->getTypeName(relocname))) continue;
384       if (error(ri->getAddress(address))) continue;
385       if (error(ri->getValueString(valuestr))) continue;
386       outs() << address << " " << relocname << " " << valuestr << "\n";
387     }
388     outs() << "\n";
389   }
390 }
391 
PrintSectionHeaders(const ObjectFile * o)392 static void PrintSectionHeaders(const ObjectFile *o) {
393   outs() << "Sections:\n"
394             "Idx Name          Size      Address          Type\n";
395   error_code ec;
396   unsigned i = 0;
397   for (section_iterator si = o->begin_sections(), se = o->end_sections();
398                                                   si != se; si.increment(ec)) {
399     if (error(ec)) return;
400     StringRef Name;
401     if (error(si->getName(Name))) return;
402     uint64_t Address;
403     if (error(si->getAddress(Address))) return;
404     uint64_t Size;
405     if (error(si->getSize(Size))) return;
406     bool Text, Data, BSS;
407     if (error(si->isText(Text))) return;
408     if (error(si->isData(Data))) return;
409     if (error(si->isBSS(BSS))) return;
410     std::string Type = (std::string(Text ? "TEXT " : "") +
411                         (Data ? "DATA " : "") + (BSS ? "BSS" : ""));
412     outs() << format("%3d %-13s %09" PRIx64 " %017" PRIx64 " %s\n",
413                      i, Name.str().c_str(), Size, Address, Type.c_str());
414     ++i;
415   }
416 }
417 
PrintSectionContents(const ObjectFile * o)418 static void PrintSectionContents(const ObjectFile *o) {
419   error_code ec;
420   for (section_iterator si = o->begin_sections(),
421                         se = o->end_sections();
422                         si != se; si.increment(ec)) {
423     if (error(ec)) return;
424     StringRef Name;
425     StringRef Contents;
426     uint64_t BaseAddr;
427     if (error(si->getName(Name))) continue;
428     if (error(si->getContents(Contents))) continue;
429     if (error(si->getAddress(BaseAddr))) continue;
430 
431     outs() << "Contents of section " << Name << ":\n";
432 
433     // Dump out the content as hex and printable ascii characters.
434     for (std::size_t addr = 0, end = Contents.size(); addr < end; addr += 16) {
435       outs() << format(" %04" PRIx64 " ", BaseAddr + addr);
436       // Dump line of hex.
437       for (std::size_t i = 0; i < 16; ++i) {
438         if (i != 0 && i % 4 == 0)
439           outs() << ' ';
440         if (addr + i < end)
441           outs() << hexdigit((Contents[addr + i] >> 4) & 0xF, true)
442                  << hexdigit(Contents[addr + i] & 0xF, true);
443         else
444           outs() << "  ";
445       }
446       // Print ascii.
447       outs() << "  ";
448       for (std::size_t i = 0; i < 16 && addr + i < end; ++i) {
449         if (std::isprint(Contents[addr + i] & 0xFF))
450           outs() << Contents[addr + i];
451         else
452           outs() << ".";
453       }
454       outs() << "\n";
455     }
456   }
457 }
458 
PrintCOFFSymbolTable(const COFFObjectFile * coff)459 static void PrintCOFFSymbolTable(const COFFObjectFile *coff) {
460   const coff_file_header *header;
461   if (error(coff->getHeader(header))) return;
462   int aux_count = 0;
463   const coff_symbol *symbol = 0;
464   for (int i = 0, e = header->NumberOfSymbols; i != e; ++i) {
465     if (aux_count--) {
466       // Figure out which type of aux this is.
467       if (symbol->StorageClass == COFF::IMAGE_SYM_CLASS_STATIC
468           && symbol->Value == 0) { // Section definition.
469         const coff_aux_section_definition *asd;
470         if (error(coff->getAuxSymbol<coff_aux_section_definition>(i, asd)))
471           return;
472         outs() << "AUX "
473                << format("scnlen 0x%x nreloc %d nlnno %d checksum 0x%x "
474                          , unsigned(asd->Length)
475                          , unsigned(asd->NumberOfRelocations)
476                          , unsigned(asd->NumberOfLinenumbers)
477                          , unsigned(asd->CheckSum))
478                << format("assoc %d comdat %d\n"
479                          , unsigned(asd->Number)
480                          , unsigned(asd->Selection));
481       } else
482         outs() << "AUX Unknown\n";
483     } else {
484       StringRef name;
485       if (error(coff->getSymbol(i, symbol))) return;
486       if (error(coff->getSymbolName(symbol, name))) return;
487       outs() << "[" << format("%2d", i) << "]"
488              << "(sec " << format("%2d", int(symbol->SectionNumber)) << ")"
489              << "(fl 0x00)" // Flag bits, which COFF doesn't have.
490              << "(ty " << format("%3x", unsigned(symbol->Type)) << ")"
491              << "(scl " << format("%3x", unsigned(symbol->StorageClass)) << ") "
492              << "(nx " << unsigned(symbol->NumberOfAuxSymbols) << ") "
493              << "0x" << format("%08x", unsigned(symbol->Value)) << " "
494              << name << "\n";
495       aux_count = symbol->NumberOfAuxSymbols;
496     }
497   }
498 }
499 
PrintSymbolTable(const ObjectFile * o)500 static void PrintSymbolTable(const ObjectFile *o) {
501   outs() << "SYMBOL TABLE:\n";
502 
503   if (const COFFObjectFile *coff = dyn_cast<const COFFObjectFile>(o))
504     PrintCOFFSymbolTable(coff);
505   else {
506     error_code ec;
507     for (symbol_iterator si = o->begin_symbols(),
508                          se = o->end_symbols(); si != se; si.increment(ec)) {
509       if (error(ec)) return;
510       StringRef Name;
511       uint64_t Address;
512       SymbolRef::Type Type;
513       uint64_t Size;
514       uint32_t Flags;
515       section_iterator Section = o->end_sections();
516       if (error(si->getName(Name))) continue;
517       if (error(si->getAddress(Address))) continue;
518       if (error(si->getFlags(Flags))) continue;
519       if (error(si->getType(Type))) continue;
520       if (error(si->getSize(Size))) continue;
521       if (error(si->getSection(Section))) continue;
522 
523       bool Global = Flags & SymbolRef::SF_Global;
524       bool Weak = Flags & SymbolRef::SF_Weak;
525       bool Absolute = Flags & SymbolRef::SF_Absolute;
526 
527       if (Address == UnknownAddressOrSize)
528         Address = 0;
529       if (Size == UnknownAddressOrSize)
530         Size = 0;
531       char GlobLoc = ' ';
532       if (Type != SymbolRef::ST_Unknown)
533         GlobLoc = Global ? 'g' : 'l';
534       char Debug = (Type == SymbolRef::ST_Debug || Type == SymbolRef::ST_File)
535                    ? 'd' : ' ';
536       char FileFunc = ' ';
537       if (Type == SymbolRef::ST_File)
538         FileFunc = 'f';
539       else if (Type == SymbolRef::ST_Function)
540         FileFunc = 'F';
541 
542       outs() << format("%08" PRIx64, Address) << " "
543              << GlobLoc // Local -> 'l', Global -> 'g', Neither -> ' '
544              << (Weak ? 'w' : ' ') // Weak?
545              << ' ' // Constructor. Not supported yet.
546              << ' ' // Warning. Not supported yet.
547              << ' ' // Indirect reference to another symbol.
548              << Debug // Debugging (d) or dynamic (D) symbol.
549              << FileFunc // Name of function (F), file (f) or object (O).
550              << ' ';
551       if (Absolute)
552         outs() << "*ABS*";
553       else if (Section == o->end_sections())
554         outs() << "*UND*";
555       else {
556         StringRef SectionName;
557         if (error(Section->getName(SectionName)))
558           SectionName = "";
559         outs() << SectionName;
560       }
561       outs() << '\t'
562              << format("%08" PRIx64 " ", Size)
563              << Name
564              << '\n';
565     }
566   }
567 }
568 
DumpObject(const ObjectFile * o)569 static void DumpObject(const ObjectFile *o) {
570   outs() << '\n';
571   outs() << o->getFileName()
572          << ":\tfile format " << o->getFileFormatName() << "\n\n";
573 
574   if (Disassemble)
575     DisassembleObject(o, Relocations);
576   if (Relocations && !Disassemble)
577     PrintRelocations(o);
578   if (SectionHeaders)
579     PrintSectionHeaders(o);
580   if (SectionContents)
581     PrintSectionContents(o);
582   if (SymbolTable)
583     PrintSymbolTable(o);
584 }
585 
586 /// @brief Dump each object file in \a a;
DumpArchive(const Archive * a)587 static void DumpArchive(const Archive *a) {
588   for (Archive::child_iterator i = a->begin_children(),
589                                e = a->end_children(); i != e; ++i) {
590     OwningPtr<Binary> child;
591     if (error_code ec = i->getAsBinary(child)) {
592       // Ignore non-object files.
593       if (ec != object_error::invalid_file_type)
594         errs() << ToolName << ": '" << a->getFileName() << "': " << ec.message()
595                << ".\n";
596       continue;
597     }
598     if (ObjectFile *o = dyn_cast<ObjectFile>(child.get()))
599       DumpObject(o);
600     else
601       errs() << ToolName << ": '" << a->getFileName() << "': "
602               << "Unrecognized file type.\n";
603   }
604 }
605 
606 /// @brief Open file and figure out how to dump it.
DumpInput(StringRef file)607 static void DumpInput(StringRef file) {
608   // If file isn't stdin, check that it exists.
609   if (file != "-" && !sys::fs::exists(file)) {
610     errs() << ToolName << ": '" << file << "': " << "No such file\n";
611     return;
612   }
613 
614   if (MachO && Disassemble) {
615     DisassembleInputMachO(file);
616     return;
617   }
618 
619   // Attempt to open the binary.
620   OwningPtr<Binary> binary;
621   if (error_code ec = createBinary(file, binary)) {
622     errs() << ToolName << ": '" << file << "': " << ec.message() << ".\n";
623     return;
624   }
625 
626   if (Archive *a = dyn_cast<Archive>(binary.get()))
627     DumpArchive(a);
628   else if (ObjectFile *o = dyn_cast<ObjectFile>(binary.get()))
629     DumpObject(o);
630   else
631     errs() << ToolName << ": '" << file << "': " << "Unrecognized file type.\n";
632 }
633 
main(int argc,char ** argv)634 int main(int argc, char **argv) {
635   // Print a stack trace if we signal out.
636   sys::PrintStackTraceOnErrorSignal();
637   PrettyStackTraceProgram X(argc, argv);
638   llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.
639 
640   // Initialize targets and assembly printers/parsers.
641   llvm::InitializeAllTargetInfos();
642   llvm::InitializeAllTargetMCs();
643   llvm::InitializeAllAsmParsers();
644   llvm::InitializeAllDisassemblers();
645 
646   // Register the target printer for --version.
647   cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion);
648 
649   cl::ParseCommandLineOptions(argc, argv, "llvm object file dumper\n");
650   TripleName = Triple::normalize(TripleName);
651 
652   ToolName = argv[0];
653 
654   // Defaults to a.out if no filenames specified.
655   if (InputFilenames.size() == 0)
656     InputFilenames.push_back("a.out");
657 
658   if (!Disassemble
659       && !Relocations
660       && !SectionHeaders
661       && !SectionContents
662       && !SymbolTable) {
663     cl::PrintHelpMessage();
664     return 2;
665   }
666 
667   std::for_each(InputFilenames.begin(), InputFilenames.end(),
668                 DumpInput);
669 
670   return 0;
671 }
672