llvm-objdump.cpp 21 KB

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